webentwicklung-frage-antwort-db.com.de

Verwenden von System.ComponentModel.DataAnnotations mit Entity Framework 4.0

Ich arbeite mit MVC3 und verwende Entity Framework 4.0 Entities als Modell. Bis jetzt funktioniert alles bestens, wenn es als Modell verwendet wird (alle primären Operationen/Seitengenerationen funktionieren sofort). Ich frage mich jedoch, wie Sie die gleichen robusten Beschriftungen und Validierungsinformationen erhalten, wenn Sie ein Modell manuell generieren.

Hier ist ein Beispiel von dem, was ich meine. Dies ist eine Klasse, die vom MVC3-Beispielprojekt generiert wurde:

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

Mit dem obigen Beispiel können Sie angeben, was in einem Etikett für das Feld (Anzeige) gerendert wird und welche Art von Feld (Kennwort) verwendet werden soll. Wenn ich jedoch versuche, das Entity-Framework zu verwenden und in die unten stehende Ansicht zu schieben, sehe ich, dass die automatisch generierten Beschriftungen nur die Feldnamen sind und nichts, was der Benutzer sehen soll/muss:

@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

Meine Frage ist: Wie füge ich diese zusätzlichen Dekorationen zu den Entitäten hinzu, die mit EF4 generiert werden? Gibt es etwas anderes als System.ComponentModel.DataAnnotations, das ich verwenden sollte? Ich weiß, dass Entitäten regeneriert werden, und es ist wahrscheinlich keine gute Idee, dies direkt in den Entitäten-Code einzufügen, aber aus irgendeinem Grund kann ich mir keinen besseren Ansatz vorstellen, als den Etikettentext manuell in die Ansicht einzugeben (lahm, es gibt keinen Grund dafür muss das tun, das ist MVC!). Ich möchte, dass die Anwendung dynamisch genug ist, um die richtigen Anzeigeinformationen für mein Modell durchlaufen zu lassen und einen MVC-Ansatz beizubehalten. Wie mache ich es?

50
Ryan Hayes

Ich habe dies nicht für ASP.NET MVC gemacht (nur für Silverlight), aber ich glaube, dass die gleichen Prinzipien zutreffen würden. Sie können eine "Metadaten-Buddy-Klasse" wie folgt erstellen, da die von EF generierten Typen partiell sein sollten. Sie können also ein wenig mehr hinzufügen (wie das MetadataTypeAttribute) und dann diese Geschwisterklasse erstellen, die die Metadaten enthält.

Es ist irgendwie hässlich, sollte aber funktionieren. Es geht ungefähr so ​​(vorausgesetzt, die EF-Entität heißt "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;
}
78
Austin Lamb

Wie oben, aber mit allen Details, und es funktioniert 

 enter image description here

 enter image description here

 enter image description here

 enter image description here

Und hier ist der 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;
    }
}
1
Arun Prasad E S

Wie Austin Lamb 's Antwort, verschachtelt stattdessen die MetaData-Klasse innerhalb der Entitätsklasse, wodurch die Anzahl der Klassen in Ihrer öffentlichen Namensraumliste reduziert wird und kein eindeutiger Name für jede Metadatenklasse erforderlich ist.

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;

            //...
        }
    }
}
0
Carter Medlin