1

В моем приложении MVC я определил DataAnnotations в моделях домена. Хотя свойства DataAnnotations как Display и т. Д. Могут быть получены при использовании модели Domain, они не могут быть получены при использовании тех же свойств в ViewModel и с использованием этой ViewModel. Я думаю, что не совсем хорошо определить DataAnnotations в ViewModel снова. Итак, возможно ли, или каким образом я должен следовать?Можно ли повторно использовать DataAnnotes в ViewModel?


домена Модель:

public class Issue 
{ 
    [Key] 
    public int ID { get; set; } 

    [Required(ErrorMessage = "Required")] 
    [Display(Name = "Project Number")] 
    public int ProjectID { get; set; } 

    [Required(ErrorMessage = "Required")] 
    [Display(Name = "Issue Definition")] 
    public string Description { get; set; } 

    //... removed for brevity 

    //Navigation Properties: 
    public virtual ICollection<FileAttachment> FileAttachments { get; set; } 
} 


ViewModel:

public class IssueViewModel 
{ 
    public int ID { get; set; } 

    public int ProjectID { get; set; } 

    public string Description { get; set; } 

    //... removed for brevity 

    //Navigation Properties: 
    public virtual ICollection<FileAttachment> FileAttachments { get; set; }  
} 
+0

Вы можете использовать прокси-класс для повторного использования аннотаций данных - это было сделано, чтобы разрешить ручные аннотации к автоматически созданным типам моделей. – Richard

+1

Вам необходимо определить их в модели представления. Но почему у вас когда-либо был атрибут '[Display]' (который как атрибут, специфичный для представления) в модели домена? –

+0

@ Рихард: Не могли бы вы разместить пример PLS? –

ответ

4

Вы можете создать new buddy класс, который содержит все метаданные о свойствах и классе.

public partial class IssueMetadata 
{ 
    [Required(ErrorMessage = "Required")] 
    [Display(Name = "Project Number")] 
    public int ProjectID { get; set; } 

    [Required(ErrorMessage = "Required")] 
    [Display(Name = "Issue Definition")] 
    public string Description { get; set; } 
} 

Тогда мы должны сказать MVC Framework о классе друзей через атрибут MetadataType, который принимает тип класса друзей в качестве аргумента. Классы Buddy должны быть определены в одном и том же пространстве имен, а также должны быть классами partial.

[MetadataType(typeof(IssueMetadata))] 
public partial class IssueViewModel 
{ 
     //... 

     public int ProjectID { get; set; } 
     public string Description { get; set; } 

     //... 
} 

[MetadataType(typeof(IssueMetadata))] 
public partial class Issue 
{ 
     [Key] 
     public int ID { get; set; } 

     public int ProjectID { get; set; } 
     public string Description { get; set; } 

     //... removed for brevity 

     //Navigation Properties: 
     public virtual ICollection<FileAttachment> FileAttachments { get; set; } 
} 

Дополнительное примечание:
Если IssueMetadata и Issue (или IssueViewModel) классов, расположенных в разных сборках, то вы можете связать классы с их приятелем класса во время выполнения, как это:

public class AssociatedMetadataConfig 
{ 
    public static void RegisterMetadatas() 
    { 
     RegisterPairOfTypes(typeof(Issue), typeof(IssueMetadata)); 
     RegisterPairOfTypes(typeof(IssueViewModel), typeof(IssueMetadata)); 
    } 

    private static void RegisterPairOfTypes(Type mainType, Type buddyType) 
    { 
     AssociatedMetadataTypeTypeDescriptionProvider typeDescriptionProvider 
      = new AssociatedMetadataTypeTypeDescriptionProvider(mainType, buddyType); 

     TypeDescriptor.AddProviderTransparent(typeDescriptionProvider, mainType); 
    } 
} 

И просто позвоните этому статическому методу в global.asax:

AssociatedMetadataConfig.RegisterMetadatas(); 
+0

Selam Farhad. Не могли бы вы разместить полный пример, содержащий классы домена и viwmodel? Потому что я никогда не использовал метаданные и не знал об этом :( –

+0

@FarhadJabiyev. Это хороший способ решить проблему. Таким образом, можно ли создать общий метаданный тип и использовать его во всех наших классах моделей? Я имею в виду, что поля в метаклассе должны использоваться в классах моделей? – ilter

+0

@ Christof Я обновил свой ответ. Вам просто нужен дополнительный класс. –

1

@ StephenMuecke является правильным. Атрибуты DomainModel и атрибуты ViewModel различны, и вы можете использовать их отдельно в своих моделях. Но я бы использовал нецелесообразность в этом случае, если бы я был вами. Вы можете создать класс Partial для ViewModel и наследовать свой DomainModel из этого класса ViewModel.

Как:

public class IssueVM 
{ 
    [Key] 
    public int ID { get; set; } 

    [Required(ErrorMessage = "Required")] 
    [Display(Name = "Project Number")] 
    public int ProjectID { get; set; } 

    [Required(ErrorMessage = "Required")] 
    [Display(Name = "Issue Definition")] 
    public string Description { get; set; } 

    //... removed for brevity 

    //Navigation Properties: 
    public virtual ICollection<FileAttachment> FileAttachments { get; set; } 
} 

public class IssueDM : IssueVM 
{ 
    // Other Fields 
} 

Таким образом, у вас есть базовый класс ViewModel (меньше полей) и более широкий класс с большим количеством полей для операций БД. Атрибуты аннотации данных ViewModel также наследуются в вашем доменном кластере таким образом.

Я не утверждаю, что это лучший способ, но я использую это и прекрасно работаю.

+0

Спасибо за ваш ответ. Это похоже на ответ Фархада, как вы сказали. С другой стороны, когда я определяю свои модели домена в слое данных и определяю режимы просмотра на веб-слое, полезно использовать метаданные. Проголосовал + –

+0

Я тебя достал. Конечно, то, что предложил @FarhadJabiyev, выглядит более элегантным способом. Я просто хотел предложить более простое решение. Его лучший ответ до сих пор :) – ilter

+0

Спасибо большое :) –

Смежные вопросы