2012-08-04 31 views
5

Tôi sẽ viết một thành phần xác thực để sử dụng nó trên các dự án khác nhau. Tôi không thực sự quen thuộc với bất kỳ khung công tác xác thực nào như Thư viện doanh nghiệp VAB, Fluent, CuttingEdge.Conditions và rất nhiều người khác, tuy nhiên tôi không có thời gian để làm việc với tất cả chúng để xem mục nào tốt hơn cho mục đích của tôi.Cách tốt nhất để xác thực giá trị tham số của phương thức WCF và WebService

Tôi muốn thành phần này để cung cấp 2 chức năng khác nhau cho tôi:

Đầu tiên, tôi muốn có một số xác nhận như EmailValidator, StringLengthValidator, MyCustomValidator và như vậy, mà tôi có thể sử dụng chúng bất cứ khi nào tôi muốn trong mã, như dưới đây:

public class EmailValidator : RegexValidator // or StringValidator or whatever! 
{ 
    public EmailValidator() : base("emailRegexHere") 
    { 
    } 
public bool override DoValidate(string value) 
    { 
     return base.DoValidate(value); 
    } 
} 
... 

public void MyMethod(string email) 
{ 
    EmailValidator validator = new EmailValidator(); 
    if(!validator.Validate(email)) 
     throw new NotValidatedException("email is invalid."); 
    ... 
} 

Second, tôi cần phải xác nhận thông số bằng cách áp dụng một cái gì đó giống như DataAnnotations cho bất kỳ tham số phương pháp mà tôi muốn mà không bất kỳ mã hóa thêm. Một cách có thể tôi biết là viết khía cạnh bằng cách sử dụng PostSharp để chèn mã nơi phương thức bắt đầu (OnMethodEntry). Tôi đã thực hiện Đăng nhập với Postsharp và nó hoạt động rất tốt.

Ngoài ra Microsoft giới thiệu IParameterInspector đến Perform Input Validation in WCF cung cấp 2 phương thức BeforCall và AfterCall, nhưng tôi nghĩ nó chỉ hoạt động cho WCF.

Để kết thúc, tôi cần phải làm xác nhận trong WCF hoặc WebService của tôi như thế này:

[System.Web.Script.Services.ScriptService] 
public class MyServiceClass : System.Web.Services.WebService 
{ 
    [Aspects.Validate] 
    [WebMethod(EnableSession = true)] 
    public string SubmitComment([Validation.Required]string content,[Validation.Guid] string userId,[Validation.Required] [Validation.Name]string name, [Validation.Email]string email, string ipAddress) 
    { 
     ... 
    } 
} 

Note: đây chỉ là một số mẫu mã để chứng minh hành vi mà tôi cần, bất cứ đề nghị khác là được đánh giá cao. Ngoài ra, ý tưởng hay là Validation. * Chú thích được thay đổi thành một chú thích như ValidateParam (typeof (EmailValidator))?

Cảm ơn trước

Trả lời

3

Vâng, tôi sẽ chỉ xem xét PostSharp cho việc này. An OnMethodBoundaryAspect hoặc MethodInterceptionAspect kiểm tra tham số của phương thức (đối với các thuộc tính nói cách xác thực) và đối số (giá trị bạn muốn xác thực).

Vì bạn đã sử dụng OnMethodBoundaryAspect trước đây, hãy xem tài liệu cho MethodExecutionArgs. Bạn có thể lấy thông tin phương thức với args.Method (trả về một MethodBase, nằm trong System.Reflection). Gọi số GetParameters() trên đó, trả về một mảng ParameterInfo. Trên mỗi đối tượng ParameterInfo, bạn có thể nhận thông tin về các thuộc tính với thuộc tính Attributes.

Một khi bạn biết các thuộc tính, thì bạn biết phương thức xác thực nào để sử dụng (hoặc nếu bạn đang tạo thuộc tính của riêng mình, phương thức xác thực có thể nằm trong các lớp thuộc tính đó). Sau đó, bạn chỉ cần sử dụng args.Arguments để lấy giá trị của các đối số.

Dưới đây là một số (psuedo) mã:

Đó không phải là mã thực: các chi tiết bạn sẽ phải làm việc ra cho mình.

Tôi thích ý tưởng đặt mã xác thực vào chính thuộc tính, vì bạn sẽ không phải thay đổi khía cạnh để thêm các loại xác thực bổ sung.

+1

Đó là chính xác những gì tôi đã có trong tâm trí, và tôi gần như hoàn thành mã hóa. Tôi tìm thấy [post] này (http://badecho.com/2011/11/validating-method-parameters-with-postsharp) bởi Matt Weber đó là hữu ích (phần đầu tiên). Về việc đặt mã xác nhận vào các thuộc tính, tôi đã thêm một phương thức giao diện 'GetValidator', vì vậy mỗi thuộc tính trả về trình xác nhận hợp lệ của nó. Vấn đề tôi gặp phải đối với các trình xác nhận chung như 'RangeValidator', vì C# không hỗ trợ các thuộc tính chung, tôi phải viết quá tải hàm dựng cho mỗi kiểu như int, double, datetime ... – Ashkan

+1

cảm ơn bằng cách này! câu trả lời của bạn làm tôi cảm thấy tốt hơn về cách tiếp cận này. Ngoài ra tôi đang viết trình xác thực của mình với FluentValidation. Tôi nghĩ nó khá tốt. – Ashkan

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