在我的ASP.Net MVC 3项目中,我希望有一个基类模型对象,它具有某些属性,然后我将在我的应用程序中的所有其他模型中使用(或至少大部分模型)。这样,使用这些派生模型的视图也将具有基类模型属性。
可以在基类控制器中设置基类模型属性,然后以某种方式我需要使用相同的数据填充派生模型。关于如何最好地完成任何建议?
或者我应该考虑以某种方式创建自己的DefaultModelBinder?我对这里的选择感到有些困惑。好像你说不出来。 :)
示例代码
基本模型
public class ElkModel
{
public bool IsAdministrator { get; set; }
}
派生模型
public class UserModel : ElkModel
{
[HiddenInput]
public int User_ID { get; set; }
// Other properties specific to this model
}
所以在基本控制器中
private BaseModel baseModel;
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
baseModel = new baseModel();
baseModel.MyProperty = "test";
base.OnActionExecuting(filterContext);
}
并在派生控制器操作方法
中public ActionResult Index()
{
// Derives from the base model in the base controller
UserModel model = new UserModel();
// model.IsAdministrator where IsAdministrator is a property of the base Model not UserModel
return View(model);
}
答案 0 :(得分:2)
如果你需要在所有视图中使用这个“公共数据”,我不会在混合中抛出继承。 我会选择一种扩展方法。
有些事情:
public static CommonData GetCommonData(this HtmlHelper htmlhelper)
{
// do your magic here
}
在您的视图中,您只需致电:
@Html.GetCommonData()...
这样可以保持模特的清洁。
继承可能是一种有效的方法,如果这个公共数据真的“适合”你的模型类。
如果你提供了一些例子,它会有所帮助; - )
**编辑**
我会将你的'BaseModel'保存为Controller中的属性,并按照你的建议在OnActionExecuting上填充它。
但我会在Controller和Html帮助器上使用ExtensionMethods来访问数据。 如果你使用继承,你将不必要地复杂化。
如果您需要扩展方法的样本,请告诉我。
这种方法很糟糕。你没有复制代码。
**编辑2 **
以下是您的扩展方法的外观:(在我的头顶,因此可能无法编译)
public static class ExtensionHelpers
{
public static BaseModel GetCommonData(this HtmlHelper htmlhelper)
{
YourController HtmlHelper = htmlhelper.ViewContext.Controller as YourController;
if (controller != null)
{
return HtmlHelper.BaseModel;
}
return null;
}
确保Controller派生自您添加BaseModel属性的Controller类。我在上面称它为'YourController'。
然后你应该好好去; - )
编辑3
提醒您,如果要在View中使用扩展方法,则需要知道命名空间。 实现此目的的最佳方法是在Views文件夹的Web.Config中包含命名空间。
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="Yournamespace" /> <- LOOK HERE
</namespaces>
</pages>
</system.web.webPages.razor>
答案 1 :(得分:1)
如果您正在谈论传入的模型或传出的模型(即提供的视图模型或由表单发布的模型参数),则取决于一点。
在前一种情况下,按照你的建议很容易做到;通过一个基本控制器,在操作执行之前或之后使用公共信息填充模型(覆盖OnActionExecuting或OnActionExecuted)。您还可以使用ActionFilter,它可能更灵活,因为它不需要您为所有控制器遵循一个继承链。出于这个原因,我倾向于推荐后一种方法。
在表单发布方面,您可能需要创建自己的模型绑定器,但只有在您有某种原因需要单个操作时才能使用多种类型的模型,并且坦率地说这可能会变得毛茸茸。在这种情况下,您必须将实际的类型名称放入隐藏的表单elemetn或其他东西,以便您的模型绑定器可以确定要实例化的模型。除非你有令人信服的理由,否则我建议不要这样做。