Click here to Skip to main content
15,879,474 members
Articles / Web Development / ASP.NET

ASP.NET MVC and jQuery Part 4 – Advanced Model Binding

Rate me:
Please Sign up or sign in to vote.
5.00/5 (10 votes)
7 May 2010CPOL7 min read 47.8K   27   2
The 4th post in a series on jQuery and ASP.NET MVC 2 in Visual Studio 2010. In this article, I'm going to look at three more complex examples of real-world model binding and where jQuery might fit in the mix.

This is the fourth post in a series about jQuery and ASP.NET MVC 2 in Visual Studio 2010.

image

In my last post, I covered the simple scenario of a Person object getting POSTed to an MVC controller using jQuery. In this article, I'm going to look at three other, more complex examples of real-world model binding and where jQuery might fit in the mix.

The model binding scenarios I'll cover are:

  • Sorting a list with jQuery UI support and submitting IDs to the controller for processing.
  • Using jQuery to augment the user experience on a list of checkboxes (supporting check all/none) and allowing MVC to handle the elegance on its own.
  • Give users the ability to build a list of items on a complex object, then submit that object to an MVC controller for processing.

The entire working solution is available for download at the end of the file.

Preface

In the first two examples here, I have lists of data that are statically programmed into the page. From my earlier posts in the series, you can see how easy it is to generate partial views that would drive the UI elements from a database or other backend. For brevity, I'm leaving those elements out of this example.

Sortable Lists

image

The jQuery UI library provides the sortable() function which transforms the children of a selected element in the DOM to draggable, orderable items for the user to manipulate.

The sortable() extension also provides a mechanism for us to capture the order of the list via the toArray method.

Using the jQuery.ajax() method, we submit the results of the users’ efforts via post to a controller action. For the purpose of this post, I'm not going to do any processing in the controller, but you can set breakpoints to see the data getting hydrated into the models.

Let’s start by setting up the controller action, which accepts a list of ints as a parameter to capture the order of the IDs.

image

Yes. It’s that simple. Now, you'd likely want to do some processing, perhaps even save the order to a database, but this is all we need to catch the data jQuery.ajax() will throw at us.

The juicy bits in jQuery are as follows:

image

Note: In order to make the results of the array compatible with the binding mechanism in ASP.NET MVC (as at MVC 2.0), we need to use the ‘traditional’ setting in $.ajax().

There are a couple of interesting things to note here:

  • jQuery.ajax() by default makes requests to the current URL via get. My controller action that accepts the List<int> is the same name as the basic view. I change the type here to POST and the proper controller action is called.
  • The ‘toArray’ returns an array of the selected element IDs.
  • My unordered list contains list items with IDs that represent the unique items. In this case, they are integers stored as strings (by nature of HTML).
  • The name of the list of IDs is passed in as the same name as the parameter in the controller action.
  • When submitted to the controller, the MVC Framework finds the appropriate method, looks at the expected parameter type and sees the array sent by the client. It then uses reflection and parsing (and maybe some voodoo) to coerce the values into the expected parameter type.

image

We can then use the list of IDs as required in the comfort of C#.

One of the interesting things that you can do, as the List<int> parameter is an IEnumerable, is that you can use LINQ to Objects on these guys without any effort. Thanks MVC Framework!

Submitting Checkboxes

image

How do you submit a list of the selected checkboxes back to an ASP.NET MVC controller action? It’s all too simple. In fact, the only reason I mention it here is to highlight some of the simplicity we inherit when we use the MVC Framework.

I actually laughed out loud when I figured this one out. It’s that good (or, I'm that easily impressed).

For jQuery on this example, I'm only really going to use it to augment the user experience by providing a couple of buttons to check all or check none of the options.

We'll use a standard HTML form and allow the user to select the items in a list they feel are appropriate. The form will be submitted via POST to our controller action (named the same as the ActionResult for the original View) and our parameter will be automatically populated for us.

image

Some things to point out at this junction:

  • The values on the checkboxes here are the same strings that are displayed in the labels.
  • I have given all the checkboxes the same name. When submitted, MVC sees these as some kind of enumerable thing and will then try to bind based on that.
  • Optimus Prime is not a Jedi.
  • The name used for the checkboxes is the same name as the parameter in the controller action.

Packing a Complex Model

image

What about if you have a complex type with properties that can't be expressed with simple HTML form fields? What if there are enumerable types as properties on the object?

Man, am I glad you asked! The ASP.NET MVC Framework is pretty smart about taking items off the client Request and building up your objects for you in the hydration process.

Here is my Suitcase class, with a List<string> that will contain all of the things that someone wants to take along on their vacation.

image

So how do we get those items into the object? The first step is to allow users to create them. We do this with a simple textbox and a button, rigged up to some jQuery script as follows:

image

When the user enters an item and clicks ‘Add to suitcase’ (or hits enter), we grab a reference to the textbox. Next, we use jQuery.append() to create a new LI element with the contents of the textbox. Finally, we clear out the value and return focus to the input field.

When the user is finished loaded up their bags, we need to create a data map that will be submitted. To simplify the process a little, we'll first get that list of clothes together.

image

We first create an empty array. Next, we use jQuery.each() to loop through all the returned elements – the list of LI elements that the user has created – and add the text of those LIs to the array.

Next, we POST the data back to the server:

image

Here are some observations:

  • We're POSTing and using the traditional setting so that the enumerated items are compatible with the current versions of jQuery and MVC.
  • The names of the properties in the Suitcase class are the names of the values we use in the data map submitted by jQuery.ajax().
  • As in the first example, jQuery.ajax() is posting to the default URL, which is the same URL as the view in this case. In the controller, we differentiate the action with the HttpPost attribute and, of course, the Suitcase parameter.

When the data is submitted, we see this in the controller action breakpoint:

image

And the contents of the Suitcase.Clothes property:

image

Wrapping Up

There you have it: the basics of advanced… stuff.

From here, you should be able to work out most scenarios when building up objects in jQuery, submitting them to the controller and making a jazzier UI come together with jQuery UI while still using MVC in the backend.

Some things I've learned along the way:

  • Remember to watch the names of your variables in data maps! They have to match the parameters (or member properties) of the controller action.
  • If you're having trouble getting things to submit and you're not seeing any errors, try attaching FireBug in FireFox to the browsing session and see what’s happening to your requests/responses.
  • Make sure that you're sending the values of the jQuery selections, and not the objects themselves if you're having trouble binding.
    • Don't send: $(“#my-textbox”)
    • Send: $(“#my-textbox”).val()

Resources

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Canada Canada
For almost 30 years I have been working with computers, learning a myriad of languages and participating in various computing environments.

Though I have been mentoring other developers for the last decade, I have recently found a strong interest in writing and am learning to translate the fun of in-person teaching to something I can get into article form.

I enjoy following technology trends, new gadgets and trying to guess where innovation will lead us next (I'm kinda holding out for a robot-served utopia, but willing to submit to our future robot leaders).

I am a guy who is passionate about my faith, my family and a cure for Juvenile Diabetes (my son lives with this disease).

Comments and Discussions

 
GeneralMy vote of 1 Pin
Paul Vinten28-Jul-15 4:06
Paul Vinten28-Jul-15 4:06 
GeneralMy vote of 5 Pin
Kshitij Banerjee6-Oct-11 22:23
Kshitij Banerjee6-Oct-11 22:23 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.