ASP.NET MVC Validation Framework when submitting via jquery $ .ajax?

There are many very good posts and explanations on how to implement validation using ASP.NET MVC, and I prefer one of them:

However, I really like to call ActionMethods the jquery $ .ajax method. One of the reasons why I want to use $ .ajax is because calls to $ .ajax will load a lot of partial views on the page dynamically (even a form for creating entities), and I can’t just return the view - I’ll lose all dynamically loaded content.

To give you a better idea of ​​the problem, I will post some simple codes to explain how I would like to invoke controller actions and process responses in the client, jquery code.

ActionMethod Controllers:

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 and processing client code:

 $.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); }}); 

Is there a good way to get some of these validation frameworks to work the way I need? I know that I can add validation errors to ActionInfo and then process it on the client, but it will be I believe that this is already building my one validation.

+6
jquery ajax validation asp.net-mvc xval
source share
2 answers

I have had great success performing validation using AJAX using data annotation attributes. To verify the correctness of your data, you will want to use the controller ModelState property, which has its own IsValid property. I highly recommend looking into the data annotation attribute attribute guide on the ASP.NET MVC official site.

First, you will want to change the action of your controller to accept the model object as a parameter, rather than a separate account name and number. This will make validation, which I will demonstrate below, much easier. From your example, I think your model object will or will be called by Customer. You may have the following code to determine the model object and the actions of your controller ...

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


Make sure the form fields are named according to the property names of the Customer object, so ASP.NET MVC can automatically link them. The "Bind" attribute in this case tells ASP.NET MVC to ignore the "Id" property of the Customer class when binding form fields to model properties. Since this is a new client, we do not yet have an identifier, so we can safely leave Id as independent of the default value and leave a data layer to determine how it is best generated.

Once the controller has built a model object for the action method, its validity can be easily checked using the ModelState.IsValid property. As expected, it will return true if the model properties are valid or false if 1 or more properties are invalid.

From the original question, it turns out that the CustomerService.InsertCustomer method throws exceptions when the validation fails. This is completely unnecessary. InsertCustomer should only perform any data operations necessary to insert a new record. If you do not want to abstract from specific implementation exceptions, such as SqlException, InsertCustomer should not really catch or throw any exceptions, but most likely just allow any exceptions to bubble up to the controller (or whoever may be the caller).

The end result of all this may be a controller action that looks like this:

 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." }); } 


If you want to report unexpected errors, such as database related exceptions, then you can add a try / catch block around the InsertCustomer call and return the necessary result to display the error message back to the client.

+5
source share

This is more than a year after you asked your question, but I looked at server side validation using Ajax calls in my blog post that might interest you. I see that you are returning unsuccessful results as successful HTTP calls. I handled it differently (I think this is more correct, since $.ajax has the ability of success and error response functions). And your specific example is a great example that can be implemented using the functions that I explain in my blog post.

Basically, instead of always returning a successful response (but with the settings configured to tell the client that the server-side processing failed), I would rather throw an exeception on the server and handle it accordingly on the client. I use the native ModelStateException class along with the HandleModelStateException action HandleModelStateException .

+2
source share

All Articles