2011-02-06 132 views
47

我正在使用MVC3,並使用Entity Framework 4.0實體作爲我的模型。到目前爲止,只要將它用作模型(所有的crud操作/頁面生成都是現成的),一切都很有效。不過,我想知道如何獲得與手動生成模型相同的健壯標籤和驗證信息?使用System.ComponentModel.DataAnnotations與實體框架4.0

下面是我的意思的例子。這是樣品MVC3項目產生的一類:

public class LogOnModel 
{ 
    [Required] 
    [Display(Name = "User name")] 
    public string UserName { get; set; } 

    [Required] 
    [DataType(DataType.Password)] 
    [Display(Name = "Password")] 
    public string Password { get; set; } 

    [Display(Name = "Remember me?")] 
    public bool RememberMe { get; set; } 
} 

有了上面的例子中,你可以指定哪些內容中的字段(顯示)標籤渲染,以及使用什麼類型的字段(密碼)。然而,當我嘗試使用實體框架,並把它推到下面的觀點,我看到了自動生成的標籤只是字段名,並沒有什麼我希望用戶看到/必須閱讀:

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>Person</legend> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.FirstName) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.FirstName) 
      @Html.ValidationMessageFor(model => model.FirstName) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.MiddleName) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.MiddleName) 
      @Html.ValidationMessageFor(model => model.MiddleName) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.LastName) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.LastName) 
      @Html.ValidationMessageFor(model => model.LastName) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Birthdate) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Birthdate) 
      @Html.ValidationMessageFor(model => model.Birthdate) 
     </div> 

     <p> 
      <input type="submit" value="Create" /> 
     </p> 
    </fieldset>} 

enter image description here

我的問題是:如何添加這些額外的裝飾到使用EF4生成的實體?除了我應該使用的System.ComponentModel.DataAnnotations之外還有什麼嗎?我知道實體被重新生成,將它直接添加到實體代碼中可能不是一個好主意,但出於某種原因,我想不出比在視圖中手動輸入標籤文本更好的方法(跛腳,沒有理由必須這樣做,這是MVC!)。我想保留它,以便應用程序足夠動態,以便能夠爲我的模型提供正確的顯示信息並保留MVC方法。我該怎麼做?

+0

相關:http://stackoverflow.com/q/2999936/11912 – 2013-03-27 14:12:33

回答

71

我還沒有爲ASP.NET MVC做這個(只適用於Silverlight),但我相信同樣的原則也適用。您可以創建一個「元數據夥伴類」,如下所示,因爲由EF生成的類型應該是部分的,因此您可以向它們添加更多元素(如MetadataTypeAttribute),然後創建包含元數據的兄弟類。

這是一種醜陋的,但應該工作。它是這樣的(假設EF實體被命名爲 「人」):

[MetadataType(typeof(PersonMetadata))] 
public partial class Person { 
    // Note this class has nothing in it. It's just here to add the class-level attribute. 
} 

public class PersonMetadata { 
    // Name the field the same as EF named the property - "FirstName" for example. 
    // Also, the type needs to match. Basically just redeclare it. 
    // Note that this is a field. I think it can be a property too, but fields definitely should work. 

    [Required] 
    [Display(Name = "First Name")] 
    public string FirstName; 
} 
+0

嗯,這是一個有趣的方法。我會嘗試一下。 – 2011-02-06 21:03:34

1

同上,但與所有的細節,以及它的工作原理

enter image description here

enter image description here

enter image description here

enter image description here

而且這裏是代碼

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.ComponentModel.DataAnnotations; 

namespace Validate.Models 
{ 
    [MetadataType(typeof(PersonMetadata))] 
    public partial class Person 
    { 
     // Note this class has nothing in it. It's just here to add the class-level attribute. 
    } 

    public class PersonMetadata 
    { 
     // Name the field the same as EF named the property - "FirstName" for example. 
     // Also, the type needs to match. Basically just redeclare it. 
     // Note that this is a field. I think it can be a property too, but fields definitely should work. 

     [Required] 
     [Display(Name = "Enter Your Name")] 
     public string FirstName; 
    } 
} 
0

奧斯汀羔羊的答案,而是嵌套MetaData類的實體類中,從而減少你的公共命名空間列表類的數量,並消除了需要爲每個元數據類使用唯一的名稱。

using System.ComponentModel.DataAnnotations; 

namespace Validate.Models 
{ 
    [MetadataType(typeof(MetaData))] 
    public partial class Person 
    { 
     public class MetaData 
     { 
      [Required] 
      [Display(Name = "Enter Your Name")] 
      public string FirstName; 

      //... 
     } 
    } 
}