What is your way of passing data to Master Page (using ASP.NET MVC) without breaking MVC rules?
Personally, I prefer to code abstract controller (base controller) or base class which is passed to all views.
What is your way of passing data to Master Page (using ASP.NET MVC) without breaking MVC rules?
Personally, I prefer to code abstract controller (base controller) or base class which is passed to all views.
Abstract controllers are a good idea, and I haven't found a better way. I'm interested to see what other people have done, as well.
I did some research and came across these two sites. Maybe they could help.
ASP.NET MVC Tip #31 – Passing Data to Master Pages and User Controls
I thing that another good way could be to create Interface for view with some Property like ParentView of some interface, so you can use it both for controls which need a reference to the page(parent control) and for master views which should be accessed from views.
I find that a common parent for all model objects you pass to the view is exceptionally useful.
There will always tend to be some common model properties between pages anyway.
If you prefer your views to have strongly typed view data classes this might work for you. Other solutions are probably more correct but this is a nice balance between design and practicality IMHO.
The master page takes a strongly typed view data class containing only information relevant to it:
public class MasterViewData
{
public ICollection<string> Navigation { get; set; }
}
Each view using that master page takes a strongly typed view data class containing its information and deriving from the master pages view data:
public class IndexViewData : MasterViewData
{
public string Name { get; set; }
public float Price { get; set; }
}
Since I don't want individual controllers to know anything about putting together the master pages data I encapsulate that logic into a factory which is passed to each controller:
public interface IViewDataFactory
{
T Create<T>()
where T : MasterViewData, new()
}
public class ProductController : Controller
{
public ProductController(IViewDataFactory viewDataFactory)
...
public ActionResult Index()
{
var viewData = viewDataFactory.Create<ProductViewData>();
viewData.Name = "My product";
viewData.Price = 9.95;
return View("Index", viewData);
}
}
Inheritance matches the master to view relationship well but when it comes to rendering partials / user controls I will compose their view data into the pages view data, e.g.
public class IndexViewData : MasterViewData
{
public string Name { get; set; }
public float Price { get; set; }
public SubViewData SubViewData { get; set; }
}
<% Html.RenderPartial("Sub", Model.SubViewData); %>
This is example code only and is not intended to compile as is. Designed for ASP.Net MVC 1.0.
EDIT
Generic Error has provided a better answer below. Please read it!
Original Answer
Microsoft has actually posted an entry on the "official" way to handle this. This provides a step-by-step walk-through with an explanation of their reasoning.
In short, they recommend using an abstract controller class, but see for yourself.
The other solutions lack elegance and take too long. I apologize for doing this very sad and impoverished thing almost an entire year later:
<script runat="server" type="text/C#">
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
MasterModel = SiteMasterViewData.Get(this.Context);
}
protected SiteMasterViewData MasterModel;
</script>
So clearly I have this static method Get() on SiteMasterViewData that returns SiteMasterViewData.
Great thread, but could someone please post a little more code?
I keep getting "; expected" after the T Create<T>() where T : MasterViewData, new()
in
public interface IViewDataFactory
{
T Create<T>() where T : MasterViewData, new()
}
code section when building my app. Do you place the ViewDataFactory
in a separate code file?
What am I doing wrong?
I prefer breaking off the data-driven pieces of the master view into partials and rendering them using Html.RenderAction. This has several distinct advantages over the popular view model inheritance approach: