2011-01-25 103 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