2011-02-06 23 views
47

Estoy trabajando con MVC3, y utilizando entidades Entity Framework 4.0 como mi modelo. Hasta ahora, todo funciona bien en cuanto a usarlo como modelo (todas las operaciones de crud/generaciones de páginas funcionan de la caja). Me pregunto, sin embargo, ¿cómo se obtienen las mismas etiquetas sólidas y la información de validación que cuando se genera un modelo manualmente?Usando System.ComponentModel.DataAnnotations con Entity Framework 4.0

Aquí hay un ejemplo de lo que quiero decir. Esta es una clase generada por el proyecto de ejemplo 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; } 
} 

Con el ejemplo anterior, se puede especificar lo que se hizo en una etiqueta para el campo (Display), y qué tipo de campo a utilizar (contraseña). Sin embargo, cuando trato de utilizar el marco de la entidad y empujarlo a la vista de abajo, veo las etiquetas generadas automáticamente son sólo los nombres de los campos, y no lo que quiera el usuario para ver/que leer:

@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

Mi pregunta es: ¿Cómo agrego estas decoraciones adicionales para las entidades que se generan utilizando EF4? ¿Hay algo más que System.ComponentModel.DataAnnotations que debería estar usando? Sé que las entidades se regeneran y probablemente no sea una buena idea agregar esto al código de las entidades directamente, pero por alguna razón no puedo pensar en un mejor enfoque que ingresar manualmente el texto de la etiqueta en la vista (cojo, no hay razón para tiene que hacer eso, ¡esto es MVC!). Quiero mantenerlo para que la aplicación sea lo suficientemente dinámica como para poder obtener la información de visualización correcta para mi modelo y mantener un enfoque MVC. ¿Cómo lo hago?

+0

relacionadas: http://stackoverflow.com/q/2999936/11912 –

Respuesta

71

No he hecho esto para ASP.NET MVC (solo para Silverlight), pero creo que se aplicarían los mismos principios. Puede crear una "clase de compañero de metadatos" como se muestra a continuación, porque los tipos generados por EF deben ser parciales, así puede agregarles un poco más (como MetadataTypeAttribute) y luego crear esta clase de hermanos que contiene los metadatos.

Es un poco feo, pero debería funcionar. Es algo parecido a esto (suponiendo que la entidad EF es nombrado "Persona"):

[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

Huh, eso es un enfoque interesante. Voy a tratar de salir. –

+2

Funciona a la perfección. Gracias, Austin! –

+0

gracias por la muestra.¿Sabe cuál es la probabilidad de que se pueda atribuir la validación al marco de entidad de modelo primero como un atributo de la propiedad de la entidad? –

1

Igual que el anterior pero con todos los detalles, y funciona

enter image description here

enter image description here

enter image description here

enter image description here

Y aquí está el código

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

Como respuesta Austin Cordero 's, pero en su lugar, anidando la clase MetaData dentro de la clase de entidad, lo que reduce el número de clases en su lista de espacio de nombres público, y la eliminación de la necesita tener un nombre único para cada clase de metadatos.

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; 

      //... 
     } 
    } 
} 
Cuestiones relacionadas