Передача метаданных / аннотаций для просмотра моделей .Net Core Razor

#c# #asp.net-core #razor #model

#c# #asp.net-core #razor #Модель

Вопрос:

У меня возникли проблемы со следующим.

У меня есть модель в пространстве имен Models SalesOrder:

 namespace MyApplication.Models
{
public class SalesOrder
{
    [Display(Name = "Sales Order ID", Description = "The internal ID for this Sales Order")]
    [Key]
    public int SalesOrderId { get; set; }

    [StringLength(100, ErrorMessage = "Order Required Time should be a maximum of 100 characters")]
    [DataType(DataType.Text)]
    [Display(Name = "Required Time", Prompt = "Enter the Time this order is required by (Optional)", Description = "The Time this order is required by the customer")]
    public string TimeRequired { get; set; }

    [StringLength(100, ErrorMessage = "Customer Order Number should be a maximum of 100 characters")]
    [DataType(DataType.Text)]
    [Display(Name = "Customer Order Number", Prompt = "Enter the Customer Order Number (Optional)", Description = "The Customer Order Number for this Order")]
    public string CustomerOrderNumber { get; set; }

    [StringLength(1000, ErrorMessage = "Special Instructions should be a maximum of 1000 characters")]
    [DataType(DataType.MultilineText)]
    [Display(Name = "Special Instructions", Prompt = "Enter the Special Instructions for this Order (Optional)", Description = "The Special Instructions for this Order")]
    public string SpecialInstructions { get; set; }
}
}  
 

Это модель, используемая для создания моих таблиц в code first.

Затем у меня есть упрощенная модель представления в пространстве имен ViewModels, которую я использую в модальном режиме для редактирования / обновления на странице:

 namespace MyApplication.ViewModels
{
public class SalesOrder
{
    public int SalesOrderId { get; set; }

    public string TimeRequired { get; set; }
}
}  
 

Это работает нормально, но я, очевидно, теряю аннотации для моего «базового класса» и, следовательно, проверку, которую я обычно получаю, на мой взгляд.

Я здесь что-то делаю неправильно?

Комментарии:

1. очевидно, что в этом сценарии нам нужно дублировать атрибуты проверки, что противоречит цели использования самого атрибута проверки (поместить логику проверки в одно место и использовать везде). Обычно вы не можете избежать такого дублирования в этом сценарии. Для лучшего решения (но более сложного), с требованием избегать дублирования атрибутов проверки, я бы объявил interface как для вашей модели сущности, так и для модели представления. Но вместо объявления конкретного класса для модели представления вы можете создать его динамически со всеми соответствующими атрибутами, клонированными из модели сущности.

2. эта идея действительно сложная, потому что, как только мы создаем класс динамически, он должен быть быстрым. EFCore и другие платформы ORM также динамически создают прокси-классы, но производительность по-прежнему достаточно высока. Так что это сложно, но выполнимо. Идея динамического создания классов view model заключается в том, чтобы позволить нам клонировать соответствующие атрибуты проверки для этих классов. Я должен сказать, что это сложно, и вы должны найти какой-нибудь существующий пакет для этого или изучить существующий исходный код, делающий то же самое. Расстояние между идеей и реальностью может быть очень большим, как в данном случае.

3. Немного покопавшись, если вы используете то же пространство имен, что и ваша базовая модель, вы можете использовать [ModelMetadataType(typeof(Модели. SalesOrder))] и аннотации применяются к соответствующим свойствам. Что вы думаете по этому поводу? Кажется, это работает. Однако мне нравится хранить мои ViewModels в другом пространстве имен.

4. это интересно, но это немного влияет на ваш дизайн. Ваш Models.SalesOrder проект entity models должен ссылаться на ваш проект entity models, что странно, потому Models.SalesOrder что он находится на уровне модели представления. Подобное смешивание 2 слоев — это просто беспорядок. Это также своего рода ограничение при использовании ModelMetadataTypeAttribute . Возможно, это EFCore создает прокси-классы, наследуемые от ваших классов сущностей, и применяет прочитанные атрибуты ModelMetadataTypeAttribute . Вот почему это работает, для других классов это не сработает.

5. другим возможным объяснением того, почему это работает, является то, что процесс проверки будет ModelMetadataTypeAttribute учитывать и вместо этого считывать атрибуты из типа метаданных. Это означает, что классы entity model могут вообще не иметь соответствующих атрибутов (даже прокси-классы, если они сгенерированы). Я просто предполагаю, потому что для подтверждения этого нам нужно сослаться на исходный код или поиграть с ним методом проб и ошибок.