There is a lot on conversation going on about binding complex JavaScript objects to ASP.NET MVC actions. Complex objects are objects that have sub objects and/or arrays.
Let’s assume the following complex model:
I have a Person object with some properties, an array of phone numbers and an Address object. I would like to pass a JavaScript representation of this object to our Controller’s Create action:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult Create(Person person) { //Code to add the person goes here //return the view return View(); }
On the client, the JavaScript representation of a Person would be:
var myPerson = { FirstName: "Nick", LastName: "Riggs", Age: 29, Address: { Street: "2780 Somewhere Far", City: "Birmingham", State: "AL" }, PhoneNumbers: [ "205-555-5634", "205-555-2294", "205-555-7681" ] };
One way to send this object to our Controller is to “stringify” the object into a JSON string using a plugin like toJSON. However, this requires us to change the Action to accept a string instead of a typed parameter, and then deserialize the string using the JavaScriptSerializer. I can get around this by automating the deserialization with a custom ActionFilterAttribute or ModelBinder. But, what if I want to use the built-in DefaultModelBinder functionality?
The default model binding in ASP.NET MVC works based on form post data. For example, if I were going to post a simple version of Person and have ASP.NET MVC map it to our action’s person parameter, I could post:
person.FirstName: Nick person.LastName: Riggs person.Age: 29
ASP.NET MVC does a good job of recognizing this post data as being a Person and mapping it as such. On top of that, it has its own simple yet powerful syntax for representing more complex objects, such as this:
person.FirstName: Nick person.LastName: Riggs person.Age: 29 person.PhoneNumbers[0]: 205-555-5634 person.PhoneNumbers[1]: 205-555-5634 person.PhoneNumbers[2]: 205-555-5634 person.Address.Street: 2780 Somewhere Far person.Address.City: Birmingham person.Address.State: AL
So, instead of stringifying my JavaScript objects, I will postify them! (I made the word postify™ up, it’s mine now). My custom postify plug-in will do the work. Here is the source code:
$.postify = function(value) { var result = {}; var buildResult = function(object, prefix) { for (var key in object) { var postKey = isFinite(key) ? (prefix != "" ? prefix : "") + "[" + key + "]" : (prefix != "" ? prefix + "." : "") + key; switch (typeof (object[key])) { case "number": case "string": case "boolean": result[postKey] = object[key]; break; case "object": if (object[key].toUTCString) result[postKey] = object[key].toUTCString().replace("UTC", "GMT"); else { buildResult(object[key], postKey != "" ? postKey : key); } } } }; buildResult(value, ""); return result; };
This is the first cut of the plug-in, and I’m sure it’s missing something – I’ll update the source code as I make updates. That said, the plug-in greatly simplifies posting complex objects to ASP.NET MVC controllers. Here is a sample in jQuery that posts myPerson:
$.ajax({ type: "POST", url: "/People/Create", data: $.postify(myPerson) });
That’s it! The plugin will handle formatting the data in an ASP.NET MVC post-friendly manner. On the server side, the parameter inflates nicely using the default model binder:
If you need to post to an action that takes multiple parameters, the complex object must be prefixed with the name of the parameter – in our case, Person. To include another parameter, use this syntax:
$.ajax({ type: "POST", url: "/JSON/DoSomething", data: $.postify({ person: myPerson, otherParam: true }) });
[…] Nick Riggs, Web Developer – Post Complex JavaScript Objects to ASP.NET MVC Controllers nickriggs.com/index.php/posts/post-complex-javascript-objects-to-asp-net-mvc-controllers – view page – cached Nick Riggs, Web Developer » Post Complex JavaScript Objects to ASP.NET MVC Controllers Comments Feed Nick Riggs, Web Developer Clean Up the setTimeout Function Simple AJAX Polling Plugin for jQuery — From the page […]
[…] to VotePost Complex JavaScript Objects to ASP.NET MVC Controllers (8/21/2009)Friday, August 21, 2009 from Nick RiggsThere is a lot on conversation going on about binding complex […]
Post Complex JavaScript Objects to ASP.NET MVC Controllers – Nick Riggs…
Thank you for submitting this cool story – Trackback from DotNetShoutout…
Nick Riggs, Web Developer – Post Complex JavaScript Objects to ASP.NET MVC Controllers…
Thank you for submitting this cool story – Trackback from progg.ru…
Nick Riggs, Web Developer – Post Complex JavaScript Objects to ASP.NET MVC Controllers…
9efish.感谢你的文章 – Trackback from 9eFish…
You should use json2.js for this instead of rolling a custom function. Its JSON.stringify() does the same thing.
The bonus when using json2.js is that browser-native JSON functionality in ECMAScript 3.1 mimics Crockford’s API. So, if your code is using json2.js’ JSON.stringify/parse, it will automatically use the faster native routines when the user’s running Firefox 3.5, IE 8, or the newest builds of Chrome/Safari.
Definitely a cool alternative approach compared to creating your own ActionFilterAttribute (I wouldn’t even consider the stringify option 🙂 )
I ask this not be be contrarian, but just a question…what does this method buy you that an ActionFilterAttribute does not? It’d be interesting to understand the performance implications. It seems the code to do this on the client vs. deserializing JSON on the server is rather similar.
@Dave: While I like json2.js, this post was meant to address “postifing” a JavaScript object so that it works within ASP.NET MVC’s default model binding. Which is something json2.js doesn’t address.
@SanjayU: All this method really buys you is integration with MVC’s default model binding behavior. It’s an custom ActionFilter you don’t have to maintain.
Nick, you’re absolutely right. I’m so used to POSTing JSON strings to ASMX/WCF services, I misunderstood what you were trying to do. Sorry about that.
Out of curiosity, have you had trouble when supplying the JSON object directly to jQuery in the data parameter? If the data parameter is an object, jQuery will automatically construct and POST the appropriate serialization of the object. So far, I haven’t run into a DTO object that jQuery’s auto-serialization didn’t properly hand off to MVC’s model binder.
Hey Nick, this is really good stuff. I’d like to use it in some of my own projects. Would you please consider attaching a license to this code to make this easier?
Wonderfull, You saved me from a LOT of trouble. Thanks a lot!!!!!
[…] the JavaScript objects into a post that MVC can bind to the controller, we are going to use the postify.js plugin I wrote back in August. That will make handling the saveButton’s click straight […]
good job, i was looking for a thing like this.
thanks a lot.
You helped me work though a problem, but I favor a simpler solution than a new plug in –
I add a string “NameField” to my ViewModel and then adjust the name of my Serializable object to that name:
Model.NameField = “Family.Children[” + i.ToString() + “]”;
easy peasy!
Thanks for the post. I am using it a lot and it really made my code simpler.
There is a bug that makes it break when one of the properties is null.
I changed it as follows.
if (object[key])
{
if (object[key].toUTCString)
{
result[postKey] = object[key].toUTCString().replace(“UTC”, “GMT”);
}
else
{
buildResult(object[key], postKey != “” ? postKey : key);
}
}
Your method here saved us precious time. You sir are a badass. Thank you.
This is sexy. Thanks. Cleaned up my code nice
<3 <3 <3
Thanks, I’ve been trying for hours to figure out how to post back multiple complex objects without writing a new model binding object for every unique request.
The first thing I would try is something like:
assuming a controller action like:
Let me know how that goes.
I can’t tell you how often I’ve turned to this plugin to solve brain dead model binding in MVC. Thanks for the quick solution that has saved many dev’s hours of screwing around with other more complex solutions for the same issue.
<3
GBtb2e http://gdjI3b7VaWpU1m0dGpvjRrcu9Fk.com
This site is crazy 🙂 preteen lolita nude thumbnails kvomak
Very funny pictures underage prelolitas porn pics rxetoy
Thanks – Nick! This is cool and indeed a very good workaround. I found one issue, if the object properties has null value it is throwing an exception. I fixed it locally as
if (object[key] == null || object[key] == undefined)
result[postKey] = object[key];
else if (object[key].toUTCString)
result[postKey] = object[key].toUTCString().replace(“UTC”, “GMT”);
else …
[…] Check out his post for details. […]
Very nice, contragulations!
Do you need a work permit? Nymphet Preteen
234106
We just spent almost two hours trying to figure out why MVC would not interpret arrays in an object. We finally figured it out it was the “dots” and then we googled for the missing dot problem and found this site. We made one small change to allow for null objects, but then it worked!!! This is awesome!!! Thank you so much.
Beautiful. Way, way better then hassling with custom action filters!
You cannot imagine how much this helps me. Thanks.
dude, you are awesome, really helpful , thanks
You Rock! I now understand what my POST issues had been…thank you
Accountant supermarket manager pornfail
whats with the nerd yellin?
I love the theatre starlist
she is made for black cocks to enjoy
Another year http://community.parents.com/asumouooi/blog/2013/04/04/lolita_kingdom_nude_pics young russiam nudist lolita Yeah bruh! Justin just dominated this chic, giving her what she didn’t think she could take. When she was beggin’ for mercy, he just kept plowing away into dat ass. In the end she was ever so grateful to him.
Remove card nude lolita bbs preteen a redheaded hot bitch with a English accent? HELL YEAH. thats on my bucket list, fuck a chick with an english accent
It’s nearly impossible to find educated people on this topic, but you sound like you know what you’re talking about!
Thanks
My web blog – where can you get bed bugs
Saved as a favorite, I love your web site!
Visit my blog post http://venarodsbloggen.wordpress.com/
so so cool, it solved my problem! thanks for that.
I just added if(object[key]) before the switch case.
Asking questions are genuinely good thing if you are not understanding something entirely, however this article gives pleasant understanding even.
Hey there, merely observe your own blog site through The search engines, and located that must be actually beneficial. I’m gonna be careful intended for the town. Let me get pleasure from if you progress this particular later on. Various other folks will more likely taken advantage of your publishing. Cheers!
Incredible, Thank you!
Really awesome man!! thanks a lot
hello!,I love your writing so a lot! share we be in contact more about your post on AOL?
I require an expert in this house to solve my
problem. Maybe that’s you! Looking ahead to see you.
My blog – click through the next website
[…] workaroand is the solution which I found here http://www.nickriggs.com/posts/post-complex-javascript-objects-to-asp-net-mvc-controllers/ It’s called postify as its author […]
[…] This plugin was found here http://www.nickriggs.com/posts/post-complex-javascript-objects-to-asp-net-mvc-controllers/ […]
Hey There. I discovered your blog using msn. That is a really smartly written article.
I will make sure to bookmark it and return to read extra of your helpful info.
Thank you for the post. I’ll definitely comeback.
This is the right web site for anybody who would like to find
out about this topic. You realize a whole lot its almost tough to argue with
you (not that I actually will need to…HaHa). You definitely put a new spin on a
subject that has been written about for a long time. Excellent
stuff, just wonderful!
[…] If you send a complex JSON object to the server your model will be initialized without nested objects. In order to overcome that you want use a function which converts JSON data to be MVC model binding compliant. The good jQuery plugin which implements that is $.postfix() which I found here http://www.nickriggs.com/posts/post-complex-javascript-objects-to-asp-net-mvc-controllers […]
This is EXACTLY what I was looking for! VERY elegant approach! Thanks!
Why people still use to read news papers when in this technological
globe all is available on net?
no words to describe the joy
no kidding
thank you much for it