The ASP.NET MVC framework supports typed view data through the ViewPage<T> and ViewMasterPage<T> classes. Using these two classes together however, imposes a constraint caused by the generics involved; any ViewMasterPage<T> can only be used as the master page for pages that have the same type of view data. This means you cannot have a ViewMasterPage<T1> and then use that as the master for ViewPage<T2>, even if T2 inherits from T1.
For now, I’m using the following polymorphism trick to get around this:
public partial class Product : ViewPage<ApplicationInfo>
{
ViewDataDictionary<ProductInfo> _viewData;
public new ViewDataDictionary<ProductInfo> ViewData
{
get
{
if (null == _viewData) _viewData = base.ViewData.Convert<ApplicationInfo, ProductInfo>();
return _viewData;
}
}
}
The Convert() extension method is defined like this:
public static class ViewDataDictionaryHelpers
{
/// <summary>
/// Converts the view data dictionary of <typeparamref name="T"/> to a view data dictionary of <typeparamref name="TNew"/>
/// </summary>
/// <typeparam name="T">The current type of the dictionary</typeparam>
/// <typeparam name="TNew">The type of the dictionary to create</typeparam>
/// <param name="viewData">The viewdata</param>
/// <returns>The viewdata</returns>
public static ViewDataDictionary<TNew> Convert<T, TNew>(this ViewDataDictionary<T> viewData)
where T : class
where TNew : class, T
{
ViewDataDictionary<TNew> newViewData = new ViewDataDictionary<TNew>((TNew)viewData.Model);
foreach (KeyValuePair<string, object> value in viewData)
{
newViewData[value.Key] = value.Value;
}
return newViewData;
}
}
It’s the best solution I’ve come up with so far, but I’m not perfectly happy with it. If you have any better ideas, leave a comment!