asp.net-mvc 在 Entity Framework 4.0 中使用 System.ComponentModel.DataAnnotations

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4915957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:51:25  来源:igfitidea点击:

Using System.ComponentModel.DataAnnotations with Entity Framework 4.0

asp.net-mvcasp.net-mvc-3c#-4.0entity-framework-4

提问by Ryan Hayes

I'm working with MVC3, and using Entity Framework 4.0 Entities as my model. So far, everything works great as far as using it as a model (all the crud operations/page generations work out of the box). I'm wondering, though, how do you get the same robust labels and validation information as when you generate a model manually?

我正在使用 MVC3,并使用 Entity Framework 4.0 实体作为我的模型。到目前为止,就将其用作模型而言,一切都很好(所有 crud 操作/页面生成都开箱即用)。不过,我想知道,您如何获得与手动生成模型时相同的强大标签和验证信息?

Here's an example of what I mean. This is a class generated by the sample MVC3 project:

这是我的意思的一个例子。这是示例 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; }
}

With the example above, you can specify what gets rendered in a label for the field (Display), and what type of field to use (Password). However, when I try to use the entity framework and push it to the view below, I see the automatically generated labels are just the field names, and not anything I want the user to see/have to read:

通过上面的示例,您可以指定在标签中为字段 (Display) 呈现的内容以及要使用的字段类型 (Password)。但是,当我尝试使用实体框架并将其推送到下面的视图时,我看到自动生成的标签只是字段名称,而不是我希望用户看到/必须阅读的任何内容:

@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

在此处输入图片说明

My question is:How do I add these extra decorations to the entities that are generated using EF4? Is there something besides System.ComponentModel.DataAnnotations that I should be using? I know entities get regenerated and it's probably not a good idea to add this to entities' code directly, but for some reason I can't think of a better approach than manually entering the label text in the view (lame, there's no reason to have to do that, this is MVC!). I want to keep it so that the application is dynamic enough to be able to have the correct display information for my model come through and keep an MVC approach. How do I do it?

我的问题是:如何将这些额外的装饰添加到使用 EF4 生成的实体中?除了 System.ComponentModel.DataAnnotations 之外,还有什么我应该使用的吗?我知道实体会重新生成,直接将其添加到实体的代码中可能不是一个好主意,但出于某种原因,我想不出比在视图中手动输入标签文本更好的方法(蹩脚,没有理由必须这样做,这是MVC!)。我想保留它,以便应用程序足够动态,以便能够为我的模型提供正确的显示信息,并保持 MVC 方法。我该怎么做?

回答by Austin Lamb

I haven't done this for ASP.NET MVC (only for Silverlight) but I believe the same principles would apply. You can create a "metadata buddy class" as below, because the types generated by EF should be partial, thus you can add a bit more to them (like the MetadataTypeAttribute) and then you create this sibling class that holds the metadata.

我还没有为 ASP.NET MVC(仅适用于 Silverlight)做过这件事,但我相信同样的原则也适用。您可以创建一个“元数据伙伴类”,如下所示,因为 EF 生成的类型应该是部分的,因此您可以向它们添加更多(如 MetadataTypeAttribute),然后您创建这个保存元数据的兄弟类。

It's kind of ugly, but should work. It goes something like this (assuming the EF entity is named "Person"):

这有点丑陋,但应该有效。它是这样的(假设 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;
}

回答by Arun Prasad E S

Same as above but with all the details, and it works

与上面相同,但包含所有细节,并且有效

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

And Here is the Code

这是代码

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;
    }
}

回答by Carter Medlin

Like Austin Lamb's answer, but instead, nesting the MetaDataclass within the entity class, thereby reducing the number of classes in your public namespace list, and eliminating the need to have a unique name for each metadata class.

就像Austin Lamb的答案一样,而是将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;

            //...
        }
    }
}