Model view controller – uses multiple interfaces with MVC dataannotations and metadatatype

I am using data annotations to apply validation to MVC ViewModel, which is a combination of several Entity Framework objects and some custom logic Validation has been defined for entity objects in the interface, but how can this validation be applied to the ViewModel?

My original idea was to combine the interfaces into one and apply the combined interface to the ViewModel, but it didn't work Here are some sample codes that show what I mean:

// interfaces containing DataAnnotations implemented by entity framework classes
public interface IPerson
{
    [required]
    [Display(Name = "First Name")]
    string FirstName { get; set; }

    [required]
    [Display(Name = "Last Name")]
    string LastName { get; set; }

    [required]
    int Age { get; set; }
}
public interface IAddress
{
    [required]
    [Display(Name = "Street")]
    string Street1 { get; set; }

    [Display(Name = "")]
    string Street2 { get; set; }

    [required]
    string City { get; set; }

    [required]
    string State { get; set; }

    [required]
    string Country { get; set; }
}

// partial entity framework classes to specify interfaces
public partial class Person : IPerson {}
public partial class Address : IAddress {}

// combined interface
public interface IPersonviewmodel : IPerson,IAddress {}

// viewmodel flattening a Person with Address for use in View
[MetadataType(typeof(IPersonviewmodel))] // <--- This does not work. 
public class Personviewmodel : IPersonviewmodel
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public int Age { get; set; }

    public string Street1 { get; set; }

    public string Street2 { get; set; }

    public string City { get; set; }

    public string State { get; set; }

    public string Country { get; set; }
}

My real-world problem involves about 150 attributes on the ViewModel, so it is not as trivial as the sample. Re entering all attributes seems to be a terrible violation of dry

Any ideas on how to achieve this goal?

Solution

To make it work, you need to manually associate the interface as metadata of a concrete class

I want to be able to add multiple metadatatype attributes, but this is not allowed

[AttributeUsage(AttributeTargets.Class,AllowMultiple = false)] // Notice AllowMultiple
public sealed class MetadataTypeAttribute : Attribute

Therefore, this gives a compilation error:

[MetadataType(typeof(IPerson))] 
[MetadataType(typeof(IAddress))] // <--- Duplicate 'MetadataType' attribute 
public class Personviewmodel : IPersonviewmodel

However, only one interface works So my solution is to simply use the associatedmetadatatypedescriptionprovider to associate the interface and wrap it in another property

[AttributeUsage(AttributeTargets.Class,AllowMultiple = true)]
public class MetadataTypeBuddyAttribute : Attribute
{
    public MetadataTypeBuddyAttribute(Type modelType,Type buddyType)
    {
        TypeDescriptor.AddProviderTransparent(
           new AssociatedMetadataTypeTypeDescriptionProvider(
               modelType,buddyType
           ),modelType);
    }
}

In my case (mvc4), the data annotation attribute on my interface has worked This is because my model implements the interface directly, not with multi-level inheritance However, custom validation properties implemented at the interface level do not work

Only when you manually associate interfaces will all custom validation work accordingly If I understand your situation, this is also the solution to your problem

[MetadataTypeBuddy(typeof(Personviewmodel),typeof(IPerson))] 
[MetadataTypeBuddy(typeof(Personviewmodel),typeof(IAddress))]
public class Personviewmodel : IPersonviewmodel
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>