2011-01-25 105 views
1

在我的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); 
} 

回答

2

如果您在所有视图中都需要这个“常用数据”,我不会在继承中混合使用继承。 我会去一个扩展方法。

线沿线的东西:

public static CommonData GetCommonData(this HtmlHelper htmlhelper) 
     { 
      // do your magic here 
     } 

在您的视图,那么你可以直接电话咨询:

@Html.GetCommonData()... 

你保持你的模型更清洁的方式。

如果此Common Data与您的Model类非常匹配,则继承可能是一种有效的方法。

,如果你提供这将有助于一些例子;-)

**编辑**

我会保持你的“BaseModel”作为控制器的属性并填充它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属性。我在上面称它为'YourController'。

那么你应该去的好;-)

编辑3

只是一个提醒,该命名空间需要知道,如果你想使用扩展方法的视图。 实现此目的的最佳方法是在您的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

取决于如果你在谈论传入的模型或即将退市的车型一点上(即视图模型提供或模型参数由表单发布)。

在前一种情况下,按照您的建议很容易;通过一个基本控制器,在动作执行之前或之后,填充模型w /通用信息(覆盖OnActionExecuting或OnActionExecuted)。你也可以使用ActionFilter,它可能更灵活,因为它不要求你为所有控制器遵循一个继承链。出于这个原因,我倾向于推荐后一种方法。

在表单邮寄方面,您可能需要创建自己的模型绑定器,但前提是您有某种原因需要单个操作采用多种类型的模型,并且坦率地说可能会发生毛病。在这种情况下,您必须将实际的类型名称放入隐藏的表单elemetn中,以便您的模型联编程序可以确定要实例化的模型。除非你有一个令人信服的理由,否则我会建议不要这种方法。

+0

嗨保罗,感谢您的快速响应。我认为我们只在这里处理输入Model/ViewModels。我将使用基本模型属性来触发页面上的某些显示(例如,Model.IsAdministrator)。 – beaudetious 2011-01-25 16:04:17

+0

好吧,所以我明白我将如何使用,例如,重写(是一个单词?)基本控制器中的OnActionExecuting方法。我有一个模型类作为该控制器的私有成员,并相应地填充它的属性。我将如何将基础模型属性导入我的模型中。在原始问题中查看我上面更新的代码示例。 – beaudetious 2011-01-25 16:11:38