2010-04-14 50 views
5

Về dự án hiện tại chúng tôi đang làm việc trên chúng tôi chưa nâng cấp lên MVC 2.0, vì vậy tôi đang thực hiện xác thực đơn giản với các công cụ có sẵn trong 1.0.Xác thực đơn giản ASP.Net MVC 1.0

Tôi đang tìm kiếm phản hồi về cách tôi đang thực hiện việc này.

Tôi có mô hình đại diện cho hồ sơ người dùng. Bên trong mô hình đó tôi có một phương thức sẽ xác nhận tất cả các trường và như vậy. Những gì tôi muốn làm là chuyển một bộ điều khiển đến phương thức xác nhận sao cho mô hình có thể thiết lập thuộc tính xác thực mô hình trong bộ điều khiển. Mục đích là để có được xác nhận từ bộ điều khiển vào mô hình.

Dưới đây là một ví dụ nhanh

public FooController : Controller 
{ 
    public ActionResult Edit(User user) 
    { 
      user.ValidateModel(this); 

      if (ModelState.IsValid) 
       ....... 
       ....... 
     } 
} 

Và xác nhận chữ ký mẫu của tôi cũng giống như

public void ValidateModel(Controller currentState) 

Những vấn đề bạn có thể thấy với điều này? Tôi có muốn ra ngoài ăn trưa về cách tôi muốn làm điều này không?

Trả lời

0

Đối với MVC 1.0 dự án chúng ta làm như sau:

/* In model class */ 

public void Validate(string dealerId) 
{ 
    ExceptionList exceptions = new ExceptionList(); 

    if (String.IsNullOrEmpty(this.UserName)) 
    { 
     exceptions.Exceptions.Add(new InvalidFieldException("Error message", "ContractType")); 
    } 

    ... other validations ... 

    if (exceptions.Exceptions.Count > 0) 
    { 
     throw exceptions; 
    } 
} 


/* In controller */ 

public virtual ActionResult UpdateProfile(User user) 
{ 

    try 
    { 
     user.Validate(); 
    } 
    catch (ExceptionList ex) 
    { 
     ex.CopyToModelState(ModelState); 
    } 
} 


/* Custom types (ExceptionList/InvalidFieldException) */ 

[Serializable] 
public class ExceptionList : Exception 
{ 
    private List<Exception> exceptions; 
    public List<Exception> Exceptions 
    { 
     get { return exceptions; } 
     set { exceptions = value; } 
    } 

    public ExceptionList() { Init(); } 
    public ExceptionList(string message) : base(message) { Init(); } 
    public ExceptionList(string message, 
     System.Exception inner) 
     : base(message, inner) { Init(); } 
    protected ExceptionList(
     System.Runtime.Serialization.SerializationInfo info, 
     System.Runtime.Serialization.StreamingContext context) 
     : base(info, context) { Init(); } 


    private void Init() 
    { 
     Exceptions = new List<Exception>(); 
    } 
} 

[Serializable] 
public class InvalidFieldException : Exception 
{ 
    private string fieldName; 
    public string FieldName 
    { 
     get 
     { 
      return fieldName; 
     } 
     set 
     { 
      fieldName = value; 
     } 
    } 

    private string fieldId; 
    public string FieldId 
    { 
     get 
     { 
      return fieldId; 
     } 
     set 
     { 
      fieldId = value; 
     } 
    } 

    public InvalidFieldException() { } 
    public InvalidFieldException(string message) : base(message) { } 
    public InvalidFieldException(string message, string fieldName) 
     : base(message) 
    { 
     this.fieldName = fieldName; 
    } 
    public InvalidFieldException(string message, string fieldName, string fieldId) 
     : base(message) 
    { 
     this.fieldName = fieldName; 
     this.fieldId = fieldId; 
    } 
    public InvalidFieldException(string message, System.Exception inner) 
     : base(message, inner) { } 
    public InvalidFieldException(string message, string fieldName, 
     System.Exception inner) 
     : base(message, inner) 
    { 
     this.fieldName = fieldName; 
    } 
    public InvalidFieldException(string message, string fieldName, string fieldId, 
     System.Exception inner) 
     : base(message, inner) 
    { 
     this.fieldName = fieldName; 
     this.fieldId = fieldId; 
    } 


    protected InvalidFieldException(
     System.Runtime.Serialization.SerializationInfo info, 
     System.Runtime.Serialization.StreamingContext context) 
     : base(info, context) { } 
} 


/* Extension method (to copy ExceptionList exceptions to ModelState) */ 

/// <summary> 
/// Copies an ExceptionList to ModelState for MVC 
/// </summary> 
/// <param name="exList">List of exceptions</param> 
/// <param name="modelState">Model state to populate</param> 
/// <param name="collection">Form collection of data posted to the action</param> 
/// <param name="prefix">Prefix used in view (if any)</param> 
/// <param name="isCollection">Indicates whether a collection of objects are being returned from the view (requires prefix)</param> 
[CLSCompliant(false)] 
public static void CopyToModelState(this ExceptionList exList, ModelStateDictionary modelState, FormCollection collection, string prefix, bool isCollection) 
{ 
    foreach (InvalidFieldException ex in exList.Exceptions) 
     if (String.IsNullOrEmpty(prefix)) 
     { 
      modelState.AddModelError(ex.FieldName, ex.Message); 
      modelState.SetModelValue(ex.FieldName, collection.ToValueProvider()[ex.FieldName]); 
     } 
     else 
     { 
      if (isCollection) 
      { 
       modelState.AddModelError(prefix + "[" + ex.FieldId + "]." + ex.FieldName, ex.Message); 
       modelState.SetModelValue(prefix + "[" + ex.FieldId + "]." + ex.FieldName, collection.ToValueProvider()[ex.FieldName]); 
      } 
      else 
      { 
       modelState.AddModelError(prefix + "." + ex.FieldName, ex.Message); 
       modelState.SetModelValue(prefix + "." + ex.FieldName, collection.ToValueProvider()[ex.FieldName]); 
      } 
     } 
} 

    /// <summary> 
    /// Copies an ExceptionList to ModelState for MVC 
    /// </summary> 
    /// <param name="exList">List of exceptions</param> 
    /// <param name="modelState">Model state to populate</param> 
    [CLSCompliant(false)] 
    public static void CopyToModelState(this ExceptionList exList, ModelStateDictionary modelState) 
    { 
     CopyToModelState(exList, modelState, null, false); 
    } 

    /// <summary> 
    /// Copies an ExceptionList to ModelState for MVC 
    /// </summary> 
    /// <param name="exList">List of exceptions</param> 
    /// <param name="modelState">Model state to populate</param> 
    /// <param name="collection">Form collection of data posted to the action</param> 
    [CLSCompliant(false)] 
    public static void CopyToModelState(this ExceptionList exList, ModelStateDictionary modelState, FormCollection collection) 
    { 
     CopyToModelState(exList, modelState, collection, null, false); 
    } 

Về cơ bản, chúng tôi chỉ ném một nhóm các trường hợp ngoại lệ trở lại với bộ điều khiển và cho phép bộ điều khiển thêm chúng vào ModelState. Khá đơn giản và kiểu mô-đun.

1

Vấn đề tôi có thể thấy với phương pháp này là logic xác thực của bạn được ghép nối với bộ điều khiển. Trên thực tế, trình xác thực không cần bộ điều khiển mà chỉ cần IDictionary<string, ModelState> để đặt lỗi.

Tôi khuyên bạn nên xem fluent validation library cho phép bạn tách hoàn toàn logic xác thực của mình khỏi bộ điều khiển. Nó sử dụng một mô hình chất kết dính trong đó nó có quyền truy cập vào bộ điều khiển để thiết lập lỗi.

Vì vậy, mã hành động của bạn sẽ trông như thế này:

public FooController : Controller 
{ 
    public ActionResult Edit(User user) 
    { 
     if (ModelState.IsValid) 
     { 

     } 
     return View(); 
    } 
} 

lỗi mẫu được thêm vào trong ràng buộc. Here's a nice article minh họa sự tích hợp của thư viện này với ASP.NET MVC. Unit testing logic xác thực của bạn cũng rất dễ đọc và dễ đọc.

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