2010-04-17 8 views
12

Używam programu VS 2010 RTM i próbuję wykonać podstawowe sprawdzanie poprawności na prostym typie przy użyciu MetadataTypeAttribute. Kiedy umieszczam atrybut sprawdzania poprawności na głównej klasie, wszystko działa. Jednak po umieszczeniu go na klasie metadanych wydaje się, że jest on ignorowany. Muszę omijać coś banalnego, ale utknąłem na tym od jakiegoś czasu..NET 4 Atrybut RTad MetadataType jest ignorowany podczas korzystania z Validatora

Podczas obejścia obejrzałem blok sprawdzania poprawności biblioteki korporacyjnej, ale nie obsługuje on sprawdzania pojedynczych właściwości po wyjęciu z pudełka. Jakieś pomysły?

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

Odpowiedz

23

Wydaje się, że Validator nie przestrzega MetadataTypeAttribute:

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

Relacja musi być jawnie zarejestrowany:

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

Ta klasa pomocnika będzie rejestrował wszystkie relacje metadanych w złożeniu:

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

Dzięki za tę doskonałą blurb kodu !! – aikeru

+0

Dlaczego nie jest to odnotowane na liście MetadataTypeAttribute w witrynie MSDN? Zostałem zawieszony na kilka godzin b/cw moim projekcie MVC wszystko działa dobrze, ale przy tworzeniu aplikacji Windows muszę być wyjaśniony –

2

Wydaje się, że działa dla mnie instancja klasy metadanych zamiast głównej dla konstruktora ValidationContext.

+0

To działało dla mnie na 'TryValidateProperty', ale nie' TryValidateObject' niestety. –

+0

@Indy potrzebowałem tylko ValidateProperty, więc użyłem tego hacka zamiast pełnego rozwiązania z zaakceptowanej odpowiedzi ze względu na krótszy kod. – SlimShaggy

+0

Dostaję "ArgumentException", że "dostarczona instancja papka pasuje do ObjectInstance na podanym potwierdzeniu poprawności". –