使用System.ComponentModel.DataAnnotations与entity framework4.0
我正在使用MVC3,并使用entity framework4.0实体作为我的模型。 到目前为止,一切都很好用,作为一个模型(所有的crud操作/页面代开箱即用)。 不过,我想知道如何获得与手动生成模型相同的健壮标签和validation信息?
这是我的意思的一个例子。 这是由示例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; } }
通过上面的示例,您可以指定在字段(显示)的标签中显示的内容,以及要使用的字段types(密码)。 但是,当我尝试使用entity framework并将其推送到下面的视图时,我看到自动生成的标签只是字段名称,而不是我希望用户看到/必须阅读的任何内容:
@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>}
我的问题是:如何将这些额外的装饰添加到使用EF4生成的实体? 除了System.ComponentModel.DataAnnotations,我应该使用什么东西吗? 我知道实体得到了重新生成,这可能不是一个好主意,直接添加到实体的代码,但出于某种原因,我想不出一个更好的方法比在视图中手动input标签文本(跛脚,没有理由必须这样做,这是MVC!)。 我想保留它,以便应用程序足够dynamic,以便能够为我的模型提供正确的显示信息,并保留MVC方法。 我该怎么做?
我没有这样做的ASP.NET MVC(只适用于Silverlight),但我相信相同的原则将适用。 您可以创build一个“元数据伙伴类”,如下所示,因为由EF生成的types应该是部分的,因此您可以为它们添加更多(如MetadataTypeAttribute),然后创build包含元数据的兄弟类。
这有点丑,但应该工作。 它是这样的(假设EF实体被命名为“Person”):
[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; }
同上,但所有的细节,它的作品
这是代码
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; } }
就像Austin Lamb的回答一样,只是将MetaData
类嵌套在实体类中,从而减less了公共名称空间列表中的类的数量,并且不需要为每个元数据类指定唯一的名称。
using System.ComponentModel.DataAnnotations; namespace Validate.Models { [MetadataType(typeof(Person.MetaData))] public partial class Person { internal class MetaData { [Required] [Display(Name = "Enter Your Name")] public string FirstName //... } } }
确保放置“。” 在typeof
函数中。