I have a _LoginPartial View and want to send data to it by ViewBag, but the Controller that I'am sending data from, doesn't have a View.
public PartialViewResult Index()
{
ViewBag.sth = // some data
return PartialView("~/Views/Shared/_LoginPartial.cshtml");
}
This code didn't work for me.
It seems you're expecting this Index action to be called when you do: #Html.Partial('_LoginPartial'). That will never happen. Partial just runs the partial view through Razor with the current view's context and spits out the generated HTML.
If you need additional information for your partial, you can specify a custom ViewDataDictionary:
#Html.Partial("_LoginPartial", new ViewDataDictionary { Foo = "Bar" });
Which you can then access inside the partial via:
ViewData["Foo"]
You can also use child actions, which is generally preferable if working with a partial view that doesn't need the context of the main view. _LoginPartial seems like a good candidate, although I'm not sure how exactly you're using it. Ironically, though, the _LoginPartial view that comes with a default MVC project with individual auth uses child actions.
Basically, the code you have would already work, you would just need to change how you reference it by using Html.Action instead of Html.Partial:
#Html.Action("Index")
Notice that you're calling the action here and now the view.
You can always pass data directly to the partial view.
public PartialViewResult Index()
{
var data = // some data
return PartialView("~/Views/Shared/_LoginPartial.cshtml", data);
}
Pass multiple pieces of data
public class MyModel
{
public int Prop1 { get; set; }
public int Prop2 { get; set; }
}
public PartialViewResult Index()
{
var data = new MyModel(){ Prop1 = 5, Prop2 = 10 };
return PartialView("~/Views/Shared/_LoginPartial.cshtml", data);
}
I passed viewBag data to my partial view like below, and I converted that viewBag data object to JSON in my partial view by using #Html.Raw(Json.Encode(ViewBag.Part));
my code sample is given below.
public async Task<ActionResult> GetJobCreationPartialView(int id)
{
try
{
var client = new ApiClient<ServiceRepairInspectionViewModel>("ServiceRepairInspection/GetById");
var resultdata = await client.Find(id);
var client2 = new ApiClient<PartViewModel>("Part/GetActive");
var partData = await client2.FindAll();
var list = partData as List<PartViewModel> ?? partData.ToList();
ViewBag.Part = list.Select(x => new SelectListItem() {Text = x.PartName, Value = x.Id.ToString()});
return PartialView("_CreateJobCardView" ,resultdata);
}
catch (Exception)
{
throw;
}
}
Here i have passed both model and viewBag .
First off, the code in your question does not run. When you do #Html.Partial("_SomeView") the Index() method you have there does not run. All #Html.Partial("_SomeView") does is render _SomeView.cshtml in your current view using the current view's ViewContext.
In order to get this to work you need a bit of functionality that's common to all the controllers in your project. You have two options: extension method for ControllerBase or a BaseController that all the controllers in your project inherit from.
Extension method:
Helper:
public static class ControllerExtensions
{
public static string GetCommonStuff(this ControllerBase ctrl)
{
// do stuff you need here
}
}
View:
#ViewContext.Controller.GetCommonStuff()
BaseController
Controller:
public class BaseController : Controller
{
public string GetCommonStuff()
{
// do stuff you need here
}
}
Other controllers:
public class SomeController : BaseController
...
...
View:
#((ViewContext.Controller as BaseController).GetCommonStuff())
Related
I have a tuble like this as model.
#model Tuple<Urun,List<UrunKatagori>>
inside the view I need to pass those data to controler.
here is the my button.
Html.X().Button().Text("Guncelle").Icon(Icon.PageSave)
.DirectEvents(de =>
{
de.Click.Url = "Urunler/Guncelle";
de.Click.ExtraParams.Add(new Parameter { Name = "Urun", Value ="Model.Item1", Mode = ParameterMode.Raw });//Iguess here is wrong
})
and my controller
[HttpPost]
public ActionResult Guncelle (Urun Urun){
Urun_BLL urun_bll = new Urun_BLL();
// urun_bll.Update(mdl);
X.Msg.Notify(new NotificationConfig
{
Icon = Icon.Accept,
Title = "Working",
Html =Urun.Ad.ToString()//I need to get data here
}).Show();
return this.Direct();
}
I strongly suggest that you create a viewmodel class, rather then passing a Tuple e.g.
public class GuncelleViewModel
{
public Urun Urun { get ;set; }
public List<UrunKatagori>> UrunKatagori { get; set; }
}
Then you can pass that to the view like so:
[HttpPost]
public ActionResult Guncelle (Urun Urun)
{
Urun_BLL urun_bll = new Urun_BLL();
// urun_bll.Update(mdl);
X.Msg.Notify(new NotificationConfig
{
Icon = Icon.Accept,
Title = "Working",
Html =Urun.Ad.ToString()//I need to get data here
}).Show();
var viewModel = new GuncelleViewModel()
viewModel.Urun = Urun;
viewModel.UrunKatagori = // TODO - However you get the categories.
return View(viewModel);
// this.Direct(); What does this.Direct() do? Replace it with calling the view instead, much cleaner.
}
In the view, use the following model
#model GuncelleViewModel
Useing a viewmodel class, which is associated one-to-one with a view file (*.cshtml), is a very good practise. It can help keep your design clean and more flexible, rather then passing specific data types, such as Tuple.
I've got an ASP.NET MVC4 project with standard controllers and views. I have to different master pages I use, depending on a global variable I can reach out and get based on the Request.Url.Host. I've written the code below but it is getting kind of bulky to put in every controller. I've gotten it pretty short but was hoping for a suggestion to make it much cleaner.
private ActionResult IndexBase(string year)
{
var data = null; // real data here for model
var localConfig = LocalConfig.GetLocalValues(Request.Url.Host, null, year);
ViewResult view = localConfig.EventType == "svcc"
? View("Index", "~/Views/Shared/_Layout.cshtml", data)
: View("Index", "~/Views/Shared/_LayoutConf.cshtml", data);
return view;
}
I don't know if this solution works for you, but I would solve it with ViewModel's and a common base controller.
One of the nice things with Layouts is you can pass a base ViewModel with the properties common to all your pages (the users name, for example). In your case, you could store the path to the Layout.
First, the base class every ViewModel derives from:
public class MasterViewModel
{
public string Name { get; set; }
public string Layout { get; set; }
}
I prefer to use a 1:1 mapping of ViewModels to Views. That is, each action gets it's own ViewModel. For example: HomeIndexViewModel for /Home/Index, ProfileEditViewModel for /Profile/Edit, etc.
public class HomeIndexViewModel : MasterViewModel
{
// properties you need for /Home/Index
}
To simplify creating the ViewModels, I add a generic method on a base controller that handles setting all these the common properties:
public class BaseController : Controller
{
protected T CreateViewModel<T>() where T : MasterViewModel, new()
{
User user = db.GetUser(User.Identity.Name);
var localConfig = LocalConfig.GetLocalValues(Request.Url.Host, null, year);
return new T()
{
Name = user.Name,
Layout = localConfig.EventType == "svcc" ? "~/Views/Shared/_Layout.cshtml"
: "~/Views/Shared/_LayoutConf.cshtml"
}
}
}
And finally, just use CreateViewModel() in each of your Actions and things should work:
public class HomeController : BaseController
{
public ActionResult Index()
{
HomeIndexViewModel viewModel = CreateViewModel<HomeIndexViewModel>();
return View(viewModel);
}
}
Inside the Views, you can just set
#model HomeIndexViewModel
#{
Layout = Model.Layout;
}
There's no need to duplicate the path anywhere, and changing the logic on which Layout to show requires you only change it in one place.
I am developing an application. I have created a view and a controller. The view has a button, on the click of which I am supposed to do database operations. I have put the database operations in the model, I am creating the object of model in the controller. On clicking the button the action is handled by a method in the controller, and the object of the model is created to get the records from the database. I would like to know if there is any way to display this data in the view.Is the approach correct or the view is supposed to interact with model directly to get the data.
Following is the code in controller that gets invoked on the button click
public ActionResult getRecord()
{
DataModel f_DM = new DataModel();
DataTable f_DT = f_DM.getRecord();
return View();
}
DataModel is the model class with simply a method "getRecord".
Any help will be highly appreciated.
I would like to add that i am using vs2010 and mvc4
Regards
you should write the logic of retrieving data in your controller. Store all your data in view model and pass it to the view.
for eg.
Model
namespace Mvc4App.Models
{
public class Product
{
public string Name { get; set; }
}
public class ProductViewModel
{
public Product Product { get; set; }
public string SalesPerson { get; set; }
}
}
Controller
public class ProductController : Controller
{
public ActionResult Info()
{
ProductViewModel ProductViewModel = new ProductViewModel
{
Product = new Product { Name = "Toy" },
SalesPerson = "Homer Simpson"
};
return View(ProductViewModel);
}
}
View
#model Mvc4App.Models.ProductViewModel
#{ ViewBag.Title = "Info"; }
<h2>Product: #Model.Product.Name</h2>
<p>Sold by: #Model.SalesPerson</p>
This is the best known practice to pass data from controller to the view.
you may use other techniques also like,
1. ViewData
2. ViewBag
3. TempData
4. View Model Object
5. Strongly-typed View Model Object
Yes, it's possible, but actually now very logical way to to this.
Lets follow your way. You have some View were you have a button, that will trigger this action.
For ex:
public ActionResult Index()
{
return View();
}
Inside view you can have a Ajax link, that will trigget your getRecord method:
<div id="GetDataDiv"></div>
<div>
#Ajax.ActionLink("Get Record", "getRecord", "ControllerName", null, new AjaxOptions() { HttpMethod = "GET", UpdateTargetId = "GetDataDiv" })
</div>
In the getRecord method you should have:
public ActionResult getRecord()
{
DataModel f_DM = new DataModel();
DataTable f_DT = f_DM.getRecord();
return PartialView(f_DT);
}
And in View it should be:
#model DataTable
#Model.PropertyOne #Model.PropertyTwo
It should works for you.
Actually same exaple here: http://www.dotnetpools.com/Article/ArticleDetiail/?articleId=151
public class SomeViewModel
{
public List<Something> listOfSomethings = new List<Something>();
public Entity EntityObj;
etc...
etc..
..
}
public class Controller()
{
public SomeViewModel viewModel;
public ActionResult SomeAction()
{
viewModel = populateViewModel();
return View(viewModel);
}
}
The SomeViewModel is a large object that is populated in the controller's action. Will it be GC'd or cleared from memory when the controller is disposed?
There is no point of this public SomeViewModel viewModel; field in your controller. Controller actions are independant meaning that if you first invoke SomeAction which sets a value for this field and then invoke some other action do not expect this field to survive. So you should simply use this:
public class HomeController: Controller
{
public ActionResult SomeAction()
{
var viewModel = populateViewModel();
return View(viewModel);
}
public ActionResult SomeOtherAction()
{
var viewModel = populateViewModel();
return View(viewModel);
}
}
This being said your current code doesn't seem to have memory leaks because once the request ends the Controller class will be eligible for GC and so all its instance fields including the view model.
if populateViewModel method does not use disaposable resources (as data context) or uses and disposes them, your code should be fine.
I am working on a project in asp.net mvc3(c#).
I need a solution for convert a view(not a partial view) to string from different controllers.
Code Explantion:
1) Calling "details" action of proposalmoduleController from proposalsController.
2) proposalmoduleController action "details" returns a view and convert this view(return result) as a string in proposalsController.
Code
public class proposalmoduleController : ControllerBase
{
[HttpGet]
public ActionResult details(int id, int widgetuniqueid)
{
//id - widgetid of div container
List<ModuleViewModel> listmoduleviewmodel = new List<ModuleViewModel>();
List<ModuleFieldViewModel> listmodulefieldviewmodel = new List<ModuleFieldViewModel>();
var objProposalModuleService = new ProposalModuleService();
var objModuleViewModel = new ModuleViewModel();
string WidgetTitle = "";
Int64 ModuleTemplateID = 0;
//objModuleViewModel.ProposalID = proposalid;
objModuleViewModel.ProposalModuleWidgetID = id;
listmoduleviewmodel=objProposalModuleService.Select(1, objModuleViewModel,out listmodulefieldviewmodel, out WidgetTitle, out ModuleTemplateID);
return View(listmoduleviewmodel);
}
}
public class proposalsController : ControllerBase
{
public string SaveHtml(int ProposalID)
{
var objProposalSortOrderViewModelList = new List<ProposalSortOrderViewModel>();
proposalmoduleController objModuleController = new proposalmoduleController(); // Initilize the object of proposalmoduleController for accessing details method
objProposalSortOrderViewModelList = GetProposalSortorders(ProposalID);
string result;
foreach (var item in objProposalSortOrderViewModelList)
{
ViewResult viewResult = (ViewResult)objModuleController.details(Convert.ToInt32(item.KeyID), Convert.ToInt32(item.SortOrder)); // Fetch the result returned from proposalmodulecontroller,details action
result=viewResult.ToString(); // Need to get result fetch from the proposalmodulecontroller,details action as a string
}
}
}
enter code here
Please suggest any solution.
A ViewResult is not a View. ViewResult is used by the MVC engine to determine the view that must be rendered.
I think it's better if you change your perspective:
if you want to include a partial view in a view just work on the presentation code using #Html.Partial
if you want to get the details data in your proposalsController don't call the action of the proposalmoduleController but call a service method that gives you the data