0

I am trying to validate a class that has a partial class and a metadata class. When I specify an attribute directly in the class, validation works, and when through metadata, then no. How do I validate my class?

public class EntityMetadata
{
    [Required] // when through metadata it doesn’t work
    public string Property { get; set; }
}

[MetadataType(typeof(EntityMetadata))]
public partial class Entity
{

}

public partial class Entity
{
    [Required] // when directly it works
    public string Property { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        Entity entity = new Entity();

        var context = new ValidationContext(entity, null, null);

        var results = new List<ValidationResult>();

        Validator.TryValidateObject(entity, context, results, true);

    }
}
r00xus
  • 79
  • 6
  • 1
    Check if [this](https://stackoverflow.com/questions/2422031/validation-does-not-work-when-i-use-validator-tryvalidateobject/2467360#2467360) resolve your problem.. – user1672994 Oct 25 '19 at 07:43
  • Is this question missing a tag? What technology uses the `[Required]` tag? – Robin Bennett Oct 25 '19 at 07:44
  • AssociatedMetadataTypeTypeDycriptionProvider registration helped. But for other entities I will have to do this constantly manually. Is there any way to get all the metadata classes attached to this class? – r00xus Oct 25 '19 at 08:08

2 Answers2

0

if you use .NETFramework v4.7.x and System.ComponentModel.DataAnnotations, you can find the validation in the result object after executing :

results[0]

Code:

        Entity entity = new Entity();

        var context = new ValidationContext(entity, null, null);

        var results = new List<ValidationResult>();

        TypeDescriptor.AddProviderTransparent(
        new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Entity), typeof(EntityMetadata)), typeof(Entity));

        Validator.TryValidateObject(entity, context, results, true);
Ahmed Msaouri
  • 316
  • 1
  • 10
  • The result of the validation goes into the results list, but there will not be a validation of the Property field using the Required attribute if it is specified in the metadata class. AssociatedMetadataTypeTypeDycriptionProvider registration helped. But for other entities I will have to do this constantly manually. Is there any way to get all the metadata classes attached to this class? – r00xus Oct 25 '19 at 08:12
  • You can create a class that inherits from Validator and override the AddProviderTransparent method and add AssociatedMetadataTypeTypeDescriptionProvider there – Ahmed Msaouri Oct 25 '19 at 09:40
0

You need to register the MetadataType with AssociatedMetadataTypeTypeDescriptionProvider.

If you want to avoid doing this for all types individually, you could call this automatically for all types in a given assembly.

using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace TestConsole
{
    public class EntityMetadata
    {
        [Required]
        public string Property { get; set; }
    }

    [MetadataType(typeof(EntityMetadata))]
    public partial class Entity
    {
    }

    public partial class Entity
    {
        public string Property { get; set; }
    }

    class Program
    {
        static void Main()
        {
            foreach (var type in typeof(Entity).Assembly.GetTypes())
            {
                TypeDescriptor.AddProvider(new AssociatedMetadataTypeTypeDescriptionProvider(type), type);
            }

            Entity entity = new Entity();
            var context = new ValidationContext(entity, null, null);
            var results = new List<ValidationResult>();

            Validator.TryValidateObject(entity, context, results, true);
        }
    }
}
Michael Sander
  • 2,677
  • 23
  • 29