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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…