Domanda

Sto usando CONTRO 2010 RTM e cercando di eseguire alcune convalida di base su un tipo semplice utilizzando MetadataTypeAttribute. Quando ho messo l'attributo convalida sulla classe principale, tutto funziona. Tuttavia, quando ho messo sulla classe di metadati, sembra essere ignorato. Devo mancare qualcosa di banale, ma sono stato bloccato su questo per un po 'di tempo.

Ho avuto uno sguardo al blocco di validazione Enterprise Library come una soluzione, ma non supporta la convalida dei singoli proprietà fuori dalla scatola. Tutte le idee?

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; }
}
È stato utile?

Soluzione

Sembra che il Validator non rispetta MetadataTypeAttribute:

http://forums.silverlight.net/forums/p/149264 /377212.aspx

Il rapporto deve essere esplicitamente iscritto:

 TypeDescriptor.AddProviderTransparent(
      new AssociatedMetadataTypeTypeDescriptionProvider(
          typeof(Stuff),
          typeof(StuffMetadata)), 
      typeof(Stuff)); 

Questa classe di supporto registrerà tutte le relazioni dei metadati in un assieme:

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;
        }
    }
}

Altri suggerimenti

Fornire un'istanza della classe di metadati anziché la classe principale al costruttore ValidationContext sembra funzionare per me.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top