One of the common tasks I encounter periodically is submitting a simple array of strings or numbers from JavaScript to a controller method for processing. It seems like I struggle often trying to make it work. So, this time I decided to develop a simple and easy to use solution. I decided to utilize custom model binder capabilities available in ASP.NET MVC. To use this method you have to define a model and a binder that will populate the model. In my case my binder assume that the data is submitted as a post or a get, pulling the data from either form collection or query string collection from the request object. It also assumes that my array is the only data submitted. In my case my model has single property – List of strings. Let’s take a look at the code.
using System.Collections.Generic; using System.Web.Mvc; namespace MyApp { [ModelBinder(typeof(ListOfStringsModelBinder))] public class ListOfStringsModel { public List<string> Numbers { get; set; } } }
The code above really does not need commenting. The only interesting part is that I specify the binder I will use for the model.
using System.Web.Mvc; using System.Web.Script.Serialization; namespace MyApp { public class ListOfStringsModelBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (controllerContext.HttpContext.Request.Form.Count > 0) { var serializer = new JavaScriptSerializer(); return serializer.Deserialize<ListOfStringsModel>(controllerContext.HttpContext.Request.Form[0]); } if (controllerContext.HttpContext.Request.QueryString.Count > 0) { var serializer = new JavaScriptSerializer(); return serializer.Deserialize<ListOfStringsModel>(controllerContext.HttpContext.Request.QueryString[0]); } return null; } } }
The code above check both form and query string trying to pull submitted data out of either. Then I use JavaScriptSerializer to push the data into the model. I could have used Json.NET just as well, but for demo purposes this is just as good. This is it. To consume this code just add ListOfStringsModel as your parameter to a controller method.
[HttpPost] public ActionResult ProcessArrayData(ListOfStringsModel model) { return null; }
Then you can use jQuery to submit the payload
function sendArray() { var payload = []; // push data into array $.ajax({ url: 'ProcessArrayData', data: JSON.stringify({ numbers: payload }), type: 'post', datatype: 'json', traditional: true, success: function (data) { }, error: function (jqXHR, textStatus, errorThrown ) { alert('Error'); } }); }
And there you go – simple and repeatable way to send array data to the server.
Enjoy.
Thanks.
If you set the contentType on the AJAX request to application/json, MVC will automatically deserialize JSON objects and arrays. You don’t need a custom model binder.
@Dave Ward
Thank you for the suggestion! I thought there has to be easier way, but I could not make it work.
How cool it is that you are reading my blog! I always thought of my blog as mostly write-only exercise with notes for myself 🙂
Pingback: Binding to Models with Array Properties in ASP.NET MVC | sharvanblog
Great post. Fantastic. Thanks for sharing this valuable inforamtion on Binding to Models with Array Properties in ASP.NET MVC.
I hope you will keep sharing more such informative articles.