2009-11-18 52 views

Trả lời

44

Bạn có thể sử dụng DataAnnotations.lớp Validator, như mô tả ở đây:

http://johan.driessen.se/archive/2009/11/18/testing-dataannotation-based-validation-in-asp.net-mvc.aspx

Nhưng nếu bạn đang sử dụng một lớp "bạn thân" cho các siêu dữ liệu, bạn cần đăng ký thực tế là trước khi bạn xác nhận, như mô tả ở đây:

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

TypeDescriptor.AddProviderTransparent(
    new AssociatedMetadataTypeTypeDescriptionProvider(typeof(myEntity), 
    typeof(myEntityMetadataClass)), 
    typeof(myEntity)); 

List<ValidationResult> results = new List<ValidationResult>(); 
ValidationContext context = new ValidationContext(myEntity, null, null) 
bool valid = Validator.TryValidateObject(myEntity, context, results, true); 

[Added sau đây để đáp ứng với bình luận Shimmy của]

Tôi đã viết một phương pháp tổng quát để thực hiện logic trên, để cho bất kỳ đối tượng có thể gọi nó là:

// If the class to be validated does not have a separate metadata class, pass 
// the same type for both typeparams. 
public static bool IsValid<T, U>(this T obj, ref Dictionary<string, string> errors) 
{ 
    //If metadata class type has been passed in that's different from the class to be validated, register the association 
    if (typeof(T) != typeof(U)) 
    { 
     TypeDescriptor.AddProviderTransparent(new AssociatedMetadataTypeTypeDescriptionProvider(typeof(T), typeof(U)), typeof(T)); 
    } 

    var validationContext = new ValidationContext(obj, null, null); 
    var validationResults = new List<ValidationResult>(); 
    Validator.TryValidateObject(obj, validationContext, validationResults, true); 

    if (validationResults.Count > 0 && errors == null) 
     errors = new Dictionary<string, string>(validationResults.Count); 

    foreach (var validationResult in validationResults) 
    { 
     errors.Add(validationResult.MemberNames.First(), validationResult.ErrorMessage); 
    } 

    if (validationResults.Count > 0) 
     return false; 
    else 
     return true; 
} 

Trong mỗi đối tượng mà cần phải được xác nhận, tôi thêm một cuộc gọi đến phương pháp này:

[MetadataType(typeof(Employee.Metadata))] 
public partial class Employee 
{ 
    private sealed class Metadata 
    { 
     [DisplayName("Email")] 
     [Email(ErrorMessage = "Please enter a valid email address.")] 
     public string EmailAddress { get; set; } 
    } 

    public bool IsValid(ref Dictionary<string, string> errors) 
    { 
     return this.IsValid<Employee, Metadata>(ref errors); 
     //If the Employee class didn't have a buddy class, 
     //I'd just pass Employee twice: 
     //return this.IsValid<Employee, Employee>(ref errors); 
    } 
} 
+0

Tôi có một lớp gazillion liên quan đến MD, bạn có ý tưởng hay không về cách liên kết nó với MD một cách năng động, nhưng tôi muốn làm theo yêu cầu, tức là chỉ khi im sẽ sử dụng lớp này (hoặc nó xác nhận) và chỉ một lần. – Shimmy

+0

@Shimmy - xem ở trên. –

+0

cảm ơn bạn! BTW, không cần đánh dấu từ điển là 'ref', vì bạn sẽ không thay đổi tham chiếu, chỉ cần truy cập thuộc tính của nó. – Shimmy

0

Sử dụng "lớp bạn thân". Số 4 trong this how-to.

+0

U liên kết được cung cấp không phải là ứng dụng trong WPF, tôi nghĩ rằng tôi đã đề cập rằng trong bài đăng của tôi. – Shimmy

4

Tôi nghĩ rằng những gì còn thiếu trong câu trả lời của Craigs là làm cách nào để kiểm tra xem có lỗi xác thực hay không. Đây là DataAnnotation xác nhận Á hậu được viết bởi Steve Sanderson cho những ai muốn để chạy kiểm tra xác nhận trong lớp mặt cầu sau đó trình bày (http://blog.codeville.net/category/xval/, mã này là trong dự án chẳng hạn):

public static IEnumerable<ErrorInfo> GetErrors(object instance) 
{ 
    var metadataAttrib = instance.GetType().GetCustomAttributes 
     (typeof(MetadataTypeAttribute), true). 
      OfType<MetadataTypeAttribute>().FirstOrDefault(); 
    var buddyClassOrModelClass = 
     metadataAttrib != null ? 
     metadataAttrib.MetadataClassType : 
     instance.GetType(); 
    var buddyClassProperties = TypeDescriptor.GetProperties 
     (buddyClassOrModelClass).Cast<PropertyDescriptor>(); 
    var modelClassProperties = TypeDescriptor.GetProperties 
     (instance.GetType()).Cast<PropertyDescriptor>(); 

    return from buddyProp in buddyClassProperties 
      join modelProp in modelClassProperties 
       on buddyProp.Name equals modelProp.Name 
      from attribute in buddyProp.Attributes. 
       OfType<ValidationAttribute>() 
      where !attribute.IsValid(modelProp.GetValue(instance)) 
      select new ErrorInfo(buddyProp.Name, 
       attribute.FormatErrorMessage(string.Empty), instance); 
} 

Tôi không quen với WPF (không chắc chắn nếu có một số giải pháp out-of-the-box cho bạn câu hỏi), nhưng có thể bạn có thể sử dụng nó.

Ngoài ra, có một số nhận xét trên blog của mình rằng trong một số trường hợp, nó không đánh giá đúng quy tắc xác thực nhưng nó không bao giờ thất bại đối với tôi.

+0

Trong WPF, nó phải được kích hoạt cho mỗi thay đổi thuộc tính. – Shimmy

+0

Đây là một cách thú vị để hoàn thành nó - Tôi có thể sửa đổi phiên bản của tôi (ở trên) với một số ý tưởng này. –

1

Tôi có cùng một câu hỏi và tìm thấy những ý tưởng sau đây:

0

tôi đã viết một Contributor validator dựa trong đó bao gồm một cộng tác viên xác nhận DataAnnotation và cũng kiểm tra đối với các ràng buộc bị hỏng (nơi người dùng đã nhập loại không chính xác)

http://adammills.wordpress.com/2010/07/21/mvvm-validation-and-type-checking/

+0

Bạn quên rằng tôi đang nói về các đối tượng thực thể được tạo ra bởi nhà thiết kế edm. – Shimmy

3

Bạn có thể quan tâm đến BookLibrary ứng dụng mẫu của WPF Application Framework (WAF). Nó thực hiện chính xác những gì bạn đang yêu cầu: sử dụng DataAnnotations trong WPF & Khuôn khổ thực thể.

Các vấn đề liên quan