Reputation: 315
Hi I'm very new to MVC
Basically what I want in webforms terms is to create a control on the master page that renders on every page associated to it, but in MVC.
So I decided that a view within a view is the best choice because I need a different model and controller than the previous view.
//Model
public class FilterViewModels
{
public Int32 CompanyID { get; set; }
public Int32 ServiceID { get; set; }
public IEnumerable<SelectListItem> Companies { get; set; }
public IEnumerable<SelectListItem> Services { get; set; }
}
//Controller
public ActionResult Filter()
{
var query = db.Companies.Select(c => new SelectListItem
{
Value = c.CompanyID.ToString(),
Text = c.Company
//,Selected = c.CompanyID.Equals(3)
});
var query1 = db.Services.Select(c => new SelectListItem
{
Value = c.ServiceID.ToString(),
Text = c.Service
});
var model = new FilterViewModels
{
Companies = query.AsEnumerable(),
Services = query1.AsEnumerable()
};
return View(model);
}
//sub view
@model SalesSystem.Models.FilterViewModels
@{
Layout = null;
}
@using (Html.BeginForm("Filter", "Filter"))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary()
@Html.DropDownListFor(m => m.CompanyID, Model.Companies)
@Html.DropDownListFor(m => m.ServiceID, Model.Services)
}
//In Main View
@RenderPage("~/Views/Filter/Filter.cshtml");
But when I run the example I get the error: "Object reference not set to an instance of an object"
The View renders correctly in the actual view but not from the main view because it isn't running the sub views controller.
Is this the wrong way of going about what I'm trying to accomplish?
Upvotes: 1
Views: 734
Reputation: 3502
You are trying to combine two query in one viewmodel. I would suggest that using dynamic ExpandoObject
to combine two query in one object. This way prevent that creating viewmodel for all query or model combinations.
You can call your partial view with Html.RenderAction("Filter", "YourController")
in desired view and You can use this way like following.
//Controller
public ActionResult Filter()
{
var listCompany = db.Companies.Select(c => new SelectListItem
{
Value = c.CompanyID,
Text = c.Company
}).ToList();
var listService = db.Services.Select(c => new SelectListItem
{
Value = c.ServiceID,
Text = c.Service
}).ToList();
dynamic yourmodel = new ExpandoObject();
yourmodel.Companies = listCompany;
yourmodel.Services = listService;
return View(yourmodel);
}
// Filter View
@using SalesSystem; // Your Project Name
@model dynamic
@{
Layout = null;
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary()
@Html.DropDownListFor(m => m.Value, new SelectList(Model.Companies, "Value", "Text"))
@Html.DropDownListFor(m => m.Value, new SelectList(Model.Services, "Value", "Text"))
}
// Desired View
@Html.RenderAction("Filter", "YourController")
Upvotes: 2
Reputation: 1612
Hi As per my knowledge you are getting this error:"Object reference not set to an instance of an object" because view page is expecting the model but it is not passed. So the solution is change the code like below.
@RenderPage("~/Views/Filter/Filter.cshtml",new {FilterData = Model});
And in the Filter.cshtml,you can access the data using the page property.
Ex:
@Page.FilterData.CompanyID
Useful Link:http://www.dotnetcurry.com/ShowArticle.aspx?ID=646
Additional Info:
You can also call the partial view using the below code:
@Html.Partial("~/Views/Filter/Filter.cshtml", Model)
Or if you want to call an action method from view :
@Html.Action("action", "controller", parameters)
Hope the above information was helpful
Thanks
Karthik
Upvotes: -1