2010-04-17 5 views
12

Tôi đang sử dụng RT 2010 VSM và cố gắng thực hiện một số xác thực cơ bản trên một loại đơn giản bằng cách sử dụng MetadataTypeAttribute. Khi tôi đặt thuộc tính xác nhận vào lớp chính, mọi thứ sẽ hoạt động. Tuy nhiên, khi tôi đặt nó vào lớp siêu dữ liệu, nó dường như bị bỏ qua. Tôi phải thiếu một thứ gì đó tầm thường, nhưng tôi đã bị mắc kẹt trong chuyện này một thời gian rồi.Thuộc tính .NET 4 RTM MetadataType bị bỏ qua khi sử dụng Validator

Tôi đã xem xét khối xác thực Thư viện doanh nghiệp dưới dạng giải pháp thay thế, nhưng không hỗ trợ xác thực các thuộc tính đơn lẻ ngoài hộp. Bất kỳ ý tưởng?

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

Trả lời

23

Dường như Validator không tôn trọng MetadataTypeAttribute:

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

Mối quan hệ phải được đăng ký explicity:

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

lớp helper này sẽ đăng ký tất cả các mối quan hệ siêu dữ liệu trong một hội đồng:

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

Cảm ơn bạn đã thực hiện điều này! – aikeru

+0

Tại sao điều này không được ghi chú trong danh sách MetadataTypeAttribute trên MSDN? Tôi đã bị treo trong một vài giờ b/c trong dự án MVC của tôi tất cả mọi thứ hoạt động tốt, nhưng khi tạo ứng dụng Windows của tôi tôi cần phải giải thích –

2

Cung cấp một thể hiện của lớp siêu dữ liệu thay vì lớp chính cho hàm tạo ValidationContext có vẻ phù hợp với tôi.

+0

Điều này làm việc cho tôi trên 'TryValidateProperty' nhưng không phải là 'TryValidateObject'. –

+0

@Andy tôi chỉ cần ValidateProperty, vì vậy tôi đã sử dụng hack này thay vì giải pháp toàn diện từ câu trả lời được chấp nhận vì lợi ích của mã ngắn hơn. – SlimShaggy

+0

Tôi nhận được một 'ArgumentException' mà' instance được cung cấp mush khớp với ObjectInstance trên validationcontext supplied'. –