2009-10-09 35 views
6

Có một rất nhiều bài rất tốt và giải thích làm thế nào để thực hiện xác nhận với ASP.NET MVC, và tôi thích một trong những:

Tuy nhiên, tôi thực sự muốn gọi ActionMethods thông qua phương thức jquery $ .ajax. Một trong những lý do tại sao tôi muốn sử dụng $ .ajax là vì sẽ có rất nhiều lượt xem một phần được tải vào trang động (ngay cả biểu mẫu để tạo thực thể) thông qua các cuộc gọi $ .ajax và tôi không thể trả về chế độ xem - Tôi sẽ mất tất cả nội dung được tải động.

Để cung cấp cho bạn một cái nhìn tốt hơn về vấn đề này, tôi sẽ đăng một số mã đơn giản để giải thích làm thế nào tôi muốn gọi hành động của bộ điều khiển và xử lý câu trả lời trong máy khách, mã jquery.

Các bộ điều khiển ActionMethod:

public ActionResult CreateCustomer(string name, string accountNumber) 
    { 
     try 
     { 
      CustomerService.InsertCustomer(name, accountNumber); 

      return Json(new ActionInfo() 
      { 
       Success = true, 
       Message = "Customer Is Successfully Created" 
      }); 

     } 
     catch (Exception ex) 
     { 
      return Json(new ActionInfo() 
      { 
       Success = false, 
       Message = ex.Message 
      }); 
     } 
    } 

Calling và xử lý trong mã khách hàng:

$.ajax({ 
type: "POST", 
url: $form.attr('action'),// /MyController/CreateCustomer 
data: $form.serialize(), 
error: HandleUnespectedError, 
dataType: "json", 
success: function(response) { 

    if (response.Success) 
     alert("Success: " + response.Message); 
    else 
     alert("Error: " + response.Message); 
}}); 

Có cách nào tốt để làm cho một số trong những khuôn khổ xác nhận để làm việc theo cách tôi cần? Tôi biết rằng tôi có thể thêm các lỗi xác thực trong ActionInfo và sau đó xử lý nó trong ứng dụng khách, nhưng đó sẽ là một tòa nhà xác thực của tôi, tôi tin.

Trả lời

5

Tôi đã có thành công lớn khi xác thực qua AJAX bằng cách sử dụng thuộc tính chú thích dữ liệu. Để kiểm tra tính hợp lệ của dữ liệu, bạn sẽ muốn sử dụng thuộc tính ModelState của bộ điều khiển, thuộc tính có thuộc tính riêng của nó được gọi là IsValid. Tôi khuyên bạn nên xem qua số data annotations validation attributes tutorial từ trang web chính thức của ASP.NET MVC.

Trước hết, bạn sẽ muốn sửa đổi hành động điều khiển của mình để chấp nhận đối tượng mô hình của mình làm tham số thay vì tên và số tài khoản riêng biệt. Điều này sẽ thực hiện việc xác nhận, mà tôi sẽ trình bày dưới đây, đơn giản hơn nhiều. Từ ví dụ của bạn, phỏng đoán tốt nhất của tôi là đối tượng mô hình của bạn là, hoặc sẽ được gọi là Khách hàng. Bạn có thể có đoạn mã sau để xác định đối tượng mô hình và hành động điều khiển của bạn ...

// model object 
public class Customer 
{ 
    public Int32 Id {get; set;} 
    public String Name {get; set;} 
    public String AccountNumber {get; set;} 
} 

// controller 
public class CustomerController : Controller 
{ 
    public ActionResult CreateCustomer([Bind(Exclude = "Id")] Customer customer) 
    { 
    // controller action code 
    } 
} 


Hãy chắc chắn rằng các lĩnh vực hình thức của bạn được đặt tên để phù hợp với tên của các thuộc tính của đối tượng khách hàng nên ASP .NET MVC có thể tự động ràng buộc chúng. Thuộc tính "Bind", trong trường hợp này, đang yêu cầu ASP.NET MVC bỏ qua thuộc tính "Id" của lớp Customer khi các trường biểu mẫu ràng buộc để mô hình các thuộc tính. Vì đây là khách hàng mới, chúng tôi chưa có Id nên chúng tôi có thể để Id một cách an toàn như bất kỳ giá trị mặc định nào và để lớp dữ liệu tìm ra cách tốt nhất để tạo ra nó.

Khi bộ điều khiển đã xây dựng đối tượng mô hình cho phương thức hành động, giá trị của nó có thể được kiểm tra dễ dàng thông qua thuộc tính ModelState.IsValid. Như người ta có thể mong đợi, nó sẽ trả về true nếu các thuộc tính mô hình là hợp lệ, hoặc false nếu 1 hoặc nhiều thuộc tính không hợp lệ.

Từ câu hỏi ban đầu, có vẻ như phương pháp CustomerService.InsertCustomer là ném ngoại lệ khi xác thực không thành công.Điều này là hoàn toàn không cần thiết. InsertCustomer chỉ cần thực hiện bất kỳ thao tác dữ liệu nào là cần thiết để chèn bản ghi mới. Trừ khi bạn muốn trừu tượng hóa các ngoại lệ cụ thể, như SqlException, InsertCustomer không thực sự cần nắm bắt hoặc ném bất kỳ ngoại lệ nào, nhưng rất có thể chỉ cho phép bất kỳ bong bóng ngoại lệ nào lên bộ điều khiển (hoặc bất kỳ người gọi nào có thể).

Kết quả cuối cùng của tất cả những điều này, có thể là một hành động điều khiển trông giống như sau:

public ActionResult CreateCustomer([Bind(Exclude = "Id")] Customer customer) 
{ 
    // model is invalid 
    if (!ModelState.IsValid) 
    { 
    return Json(new ActionInfo() 
    { 
     Success = false, 
     Message = "Validation failed" // you will probably want a more robust message :-) 
    }); 
    } 

    // service method accepts a Customer object rather than arbitrary strings 
    CustomerService.InsertCustomer(customer); 

    return Json(new ActionInfo() 
    { 
    Success = true, 
    Message = "Customer created successfully." 
    }); 

} 


Nếu bạn muốn báo cáo lỗi bất ngờ, giống như trường hợp ngoại lệ cơ sở dữ liệu liên quan, sau đó bạn chắc chắn có thể thêm một khối try/catch xung quanh lệnh gọi tới InsertCustomer, và trả lại kết quả cần thiết để hiển thị thông báo lỗi trở lại máy khách.

+0

Xin chào! Cảm ơn rất nhiều vì nỗ lực :) Tôi hoàn toàn đồng ý với bạn về thực thể khách hàng về ràng buộc (muốn làm như vậy, không biết tại sao tôi lại đặt phương thức với các tham số đơn giản) và xử lý ngoại lệ. Với xVal, tôi có thể thực hiện một cách dễ dàng xác thực ứng dụng khách, và nếu ai đó tránh nó, tôi sẽ bắt nó trong hành động. Nhưng làm thế nào tôi sẽ trình bày thông báo xác nhận bên cạnh các trường trong trường hợp đó? –

+0

Đối với điều đó, bạn sẽ muốn trả về một phần xem hơn là JSON từ hành động điều khiển của bạn. Trong chế độ xem một phần của bạn, bạn sẽ sử dụng phương thức trình trợ giúp Html.ValidationMessage() để hiển thị thông báo lỗi cho từng trường. Thông báo lỗi cấp trường được tạo bởi thuộc tính Chú thích dữ liệu của bạn có sẵn cho bộ điều khiển của bạn thông qua thuộc tính 'ModelState'. Ví dụ, để nhận được thông báo lỗi đầu tiên cho một trường được gọi là tên, bạn sẽ nhận được nó thông qua 'ModelState [" Tên "]. Lỗi [0] .ErrorMessage'. Ngoài ra, hãy xem phương thức 'Ajax.BeginForm'. Tôi đã sử dụng nó với thành công lớn trong quá khứ. –

+1

Đó là những gì tôi nhận ra, hoặc là tôi sẽ trả về JSON hoặc xem một phần, và đó là điều tôi không thích ... Tuy nhiên, tôi sẽ xem xét cách xử lý nó bằng cách sử dụng MS được xây dựng trong các tính năng Ajax, mặc dù mong muốn của tôi là để tránh điều đó :) Cảm ơn –

2

Đã hơn một năm sau khi bạn đặt câu hỏi, nhưng tôi đã trình bày xác thực phía máy chủ với các cuộc gọi Ajax trong số blog post của mình mà có thể bạn quan tâm. Tôi thấy rằng bạn trả về kết quả không thành công như các cuộc gọi HTTP thành công. Tôi đã xử lý điều này một cách khác nhau (tôi đoán nó chính xác hơn vì $.ajax có khả năng của success và chức năng phản hồi error). Và ví dụ cụ thể của bạn là một ví dụ hoàn hảo có thể được triển khai với chức năng tôi giải thích trong bài đăng trên blog của mình. Về cơ bản thay vì luôn trả về một phản hồi thành công (nhưng với các thuộc tính được thiết lập để thông báo cho khách hàng rằng việc xử lý phía máy chủ không thành công), tôi thay vì ném một hành vi lừa đảo trên máy chủ và xử lý nó cho phù hợp trên máy khách. Tôi đang sử dụng một lớp ModelStateException tùy chỉnh cùng với một bộ lọc hành động HandleModelStateException.

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