Here are some options using reflection. The performance should be negligible in most scenarios.
Utility Class
public static class ModelHelper
{
public static T Data<T>( String key)
{
var html = ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html;
var model = html.ViewData.Model;
return (T)model.GetType().GetProperty(key).GetValue(model) ;
}
}
view.cshtml
@(Html.Partial("partial",new { Id="InstructorId"}))
paritial.cshtml file
@model dynamic
@{
var id = ModelHelper.Data<String>("Id");
}
With a more compact parital call in view.cshtml
@{
var instructorId = "InstructorId";
var windowTitle = "Window Title";
var editorPageUrl = "~/View/Editors/Instructors.chstml";
}
@(Html.Partial("partial",new { instructorId, windowTitle, editorPageUrl }))
With variables adjusted to get inferred names in paritial.cshtml file
@model dynamic
@{
var id = ModelHelper.Data<String>("instructorId");
var id = ModelHelper.Data<String>("windowTitle");
var id = ModelHelper.Data<String>("editorPageUrl");
}
It is not hard to create a simple view-model class but I don't like classes that will only ever be used a single time for passing data, so this works for me.
You could also extend the default view base
namespace SafetyPlus.Shell.Code
{
public abstract class ExtendedPageBaseClass<TModel> : WebViewPage<TModel> where TModel : class
{
public T Data<T>(String key)
{
return (T)Model.GetType().GetProperty(key).GetValue(Model);
}
public Object Data(String key)
{
return Data<Object>(key);
}
}
}
Register the base class in the /Views/web.config
<pages pageBaseType="SafetyPlus.Shell.Code.ExtendedPageBaseClass">
...
</pages>
Get the data in your partial view like this
@{
var id = Data("Id");
var idTyped = Data<String>("Id");
}
Or using an extension method which I suggested against.
namespace NotYourDefaultNamespace
{
public static class ModelExtensions
{
public static T Data<T>( this Object model, String key)
{
return (T)model.GetType().GetProperty(key).GetValue(model) ;
}
}
}
This options really doesn't buy you anything since we are finding the model from within the previous utility method. The call would become.
@{
var id = Model.Data("Id");
}