When ASP. net mvc encounters jQuery. Ajax, submit an array

Source: Internet
Author: User

When ASP. net mvc submits arrays through JQuery Ajax, the model binder Mechanism of MVC becomes invalid. We have to write custom code in the Controller to convert the data submitted by the Request to the required data type. This process is often boring. The following uses a project as an example to demonstrate how to solve this problem and provide a general solution.

Requirement Description

When the user changes the configuration, Ajax must be submitted to the server.

Front-end code:

 
 
  1. var items = [];  
  2. $("input:checked").each(function () {  
  3.     items.push($(this).val());  
  4. });  
  5. $.ajax({  
  6.     type: 'post',  
  7.     url: 'Configure/Status',  
  8.     data: { answers: items }  
  9. }); 

Backend code:

 
 
  1. public enum AnswerStatus  
  2. {  
  3.         Correct = 1,  
  4.         Incorrect = 2,  
  5.         Unanswered = 3 
  6. }  
  7. [HttpPost]  
  8. public ActionResult Status(IList<AnswerStatus> answers)  
  9. {  
  10.      ….  

Here, answers is always null. The fiddler is used. It is found that the Array data is submitted using JQuery. Ajax, and "[]" is always added after the name during submission. The problem lies here.

Modify the code based on the discovered results:

 
 
  1. [HttpPost]  
  2. public ActionResult Status(IList<AnswerStatus> answers)  
  3. {  
  4.     answers = Request.Form.GetValues(“answers[]”).Select(d => d.ToEnum<AnswerStatus>(AnswerStatus.Unanswered).ToList();  

Although this can solve my problem, every time I submit an Array, I need to manually parse the request, and it will take a night to return to the stone age. In fact, we will immediately think of the MVC Mode Binder.

Try to perform the first refactoring:

 
 
  1. public class AnswerModelBinder : IModelBinder  
  2. {  
  3.     public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)  
  4.     {  
  5.         return controllerContext.RequestContext.HttpContext.Request.Form.GetValues(“answers[]”).Select(d => d.ToEnum<AnswerStatus>(AnswerStatus.Unanswered).ToList();      
  6.     }  

Hard coding tastes too heavy. You have to change the type and rewrite it. The workload is much higher than before, but the Controller becomes more elegant. This kind of waste of youth and power consumption still does not meet the requirements.

Perform the second reconstruction: ultmodelbinder appears

The omnipotent defamodelmodelbinder can be bound to any type. Unfortunately, "[]" is added after the name passed by the client, which makes the defamodelmodelbinder unable to be accurately parsed. Can we cheat defamodelmodelbinder?

You can view ModelBindingContext and find that there is a ModelName attribute, which is a bit like the name of the parameter to be bound. The debug trail finds that ModelName is indeed the name of the parameter, then we modify the ModelName so that it is consistent with the name passed by the client to make full use of defamodelmodelbinder. Create a JQAjaxModelBinder

And inherit from defamodelmodelbinder:

 
 
  1. Public override object BindModel (ControllerContext controllerContext, ModelBindingContext bindingContext)
  2. {
  3. If (bindingContext. ModelType. IsEnumerable ())
  4. {
  5. Var key = bindingContext. ModelName + "[]";
  6. Var valueResult = bindingContext. ValueProvider. GetValue (key );
  7. If (valueResult! = Null &&! String. IsNullOrEmpty (valueResult. AttemptedValue ))
  8. {
  9. BindingContext. ModelName = key;
  10. }
  11. }
  12. Return base. BindModel (controllerContext, bindingContext );
  13. } // How to use custom ModelBinder. This method is the Action in the Controller.
  14. Public ActionResult Status ([ModelBinder (typeof (ModelBinder. JQAjaxModelBinder)] IList <AnswerStatus> answers)
  15. {
  16. ...
  17. }

At this time, the Status Action Method in the Controller can correctly obtain the data sent from the front-end. It is also strongly typed. Of course, many programmers are lazy, and I am also a part of it. I don't even want to write the Parameter [ModelBinder (typeof (ModelBinder. JQAjaxModelBinder)]) before Parameter. Let's register it directly in ModelBinders. In fact, it is a little troublesome during registration. You must set the Type. I can know the types in advance. Simply set JQAjaxModelBinder to the default ModerBinder. Once and for all, there will be no worries.

ModelBinder different registration methods

Add the ModelBinder label before the parameter of the Action method. The preceding method is used.

Add the ModelBinder label to the data type.

 
 
  1. [ModelBinder(typeof(ModelBinder.JQAjaxModelBinder))]  
  2. Public class User  
  3. {  

Register through ModelBinders

 
 
  1. ModelBinders.Binders.Add(typeof(User), new ModelBinder.JQAjaxModelBinder()); 

Set the default ModerBinder

 
 
  1. ModelBinders.Binders.DefaultBinder = new ModelBinder.JQAjaxModelBinder(); 

Note: When we are developing, we often repeat things. When one thing is repeated multiple times, we need to stop and think carefully. Can we abstract these things, what about a general solution? Solve these problems once and for all.

Link: http://www.cnblogs.com/coolite/archive/2012/12/24/JQModelBinder.html

Edit recommendations]

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.