Использование System.ComponentModel.DataAnnotations с Entity Framework 4.0
Я работаю с MVC3 и использую Entity Framework 4.0 Entities в качестве моей модели. До сих пор все отлично работает, поскольку используется в качестве модели (все операции crud/генерации страниц работают из коробки). Мне интересно, однако, как вы получаете одинаковые надежные метки и данные проверки, как при создании модели вручную?
Вот пример того, что я имею в виду. Это класс, сгенерированный образцом проекта 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, которые я должен использовать? Я знаю, что объекты получаются регенерированными, и, вероятно, не рекомендуется добавлять это в код сущности напрямую, но по какой-то причине я не могу придумать более подходящий подход, чем вручную ввести текст метки в представлении (lame, нет причин для должны сделать это, это MVC!). Я хочу сохранить его таким образом, чтобы приложение было достаточно динамичным, чтобы иметь возможность отображать правильную отображаемую информацию для моей модели и поддерживать подход MVC. Как это сделать?
Ответы
Ответ 1
Я не делал этого для ASP.NET MVC (только для Silverlight), но я считаю, что будут применяться те же принципы. Вы можете создать "класс друзей метаданных", как показано ниже, потому что типы, сгенерированные EF, должны быть частичными, поэтому вы можете добавить к ним немного больше (например, атрибут MetadataTypeAttribute), а затем вы создадите этот родственный класс, содержащий метаданные.
Это вроде уродливо, но должно работать. Это происходит примерно так (предполагая, что объект EF называется "Person" ):
[MetadataType(typeof(PersonMetadata))]
public partial class Person {
// Note this class has nothing in it. It 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;
}
Ответ 2
То же, что и выше, но со всеми подробностями и работает
![введите описание изображения здесь]()
![введите описание изображения здесь]()
![введите описание изображения здесь]()
![введите описание изображения здесь]()
И вот код
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 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;
}
}
Ответ 3
Как и Остин Лэмб, но вместо этого, MetaData
класс 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;
//...
}
}
}
Ответ 4
Хорошая идея - вложить класс метаданных в частичный класс, но, к сожалению, Entity Framework всегда перезапишет его... Я работаю над MVC5, и первое решение поместить его в ту же папку, но отдельный класс работает нормально