I am using VS 2010 RTM and trying to perform some basic validation on a simple type using MetadataTypeAttribute. When I put the validation attribute on the main class, everything works. However, when I put it on the metadata class, it seems to be ignored. I must be missing something trivial, but I've been stuck on this for a while now.
I had a look at the Enterprise Library validation block as a workaround, but it doesn't support validation of single properties out of the box. Any ideas?
class Program
{
    static void Main(string[] args)
    {
        Stuff t = new Stuff();
        try
        {
            Validator.ValidateProperty(t.X, new ValidationContext(t, null, null) { MemberName = "X" });
            Console.WriteLine("Failed!");
        }
        catch (ValidationException)
        {
            Console.WriteLine("Succeeded!");
        }
    }
}
[MetadataType(typeof(StuffMetadata))]
public class Stuff
{
    //[Required]  //works here
    public string X { get; set; }
}
public class StuffMetadata
{
    [Required]  //no effect here
    public string X { get; set; }
}
It seems that the Validator doesn't respect MetadataTypeAttribute:
http://forums.silverlight.net/forums/p/149264/377212.aspx
The relationship must be explicity registered:
 TypeDescriptor.AddProviderTransparent(
      new AssociatedMetadataTypeTypeDescriptionProvider(
          typeof(Stuff),
          typeof(StuffMetadata)), 
      typeof(Stuff)); 
This helper class will register all the metadata relationships in an assembly:
public static class MetadataTypesRegister
{
    static bool installed = false;
    static object installedLock = new object();
    public static void InstallForThisAssembly()
    {
        if (installed)
        {
            return;
        }
        lock (installedLock)
        {
            if (installed)
            {
                return;
            }
            foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
            {
                foreach (MetadataTypeAttribute attrib in type.GetCustomAttributes(typeof(MetadataTypeAttribute), true))
                {
                    TypeDescriptor.AddProviderTransparent(
                        new AssociatedMetadataTypeTypeDescriptionProvider(type, attrib.MetadataClassType), type);
                }
            }
            installed = true;
        }
    }
}
Supplying an instance of the metadata class instead of the main class to the ValidationContext constructor seems to work for me.
来源:https://stackoverflow.com/questions/2657358/net-4-rtm-metadatatype-attribute-ignored-when-using-validator