Paul Ulvinius Blog

From one developer to another

The power of partial views, JQuery and AJAX in ASP.NET MVC

Posted by paululvinius on June 16, 2009

One really nice benefit you get from using ASP.NET MVC is that you get structured url:s out of the box looking like this: http://www.mycoolsite.com/Products/Create, Products/List, Products/Details, Categories/List, etc. Each url maps to an action within a “controller”, that returns a “view” that is supposed to render exactly what you expect from reading the url. So, “Products/Create” tells us that we are going to see a view, where we will be able to create a product – but enough with the obvious.

While url:s specific to user actions like this make everything very structured and maintainable, we often need to cross these boundaries. What if we want to create a “product” and a “category” from the same page? A page in a website often contains combinations of different responsibilities like this common scenario: While editing a product, a user realizes that he/she wants to create a new category for the product. To solve this nicely we might want to embed a “create category” part within the “create product” view. This is where “partial views” in ASP.NET MVC come in. Additionally, we probably don’t even want the web page to reload while adding categories, making it possible to fill in half a product form, realize that you need more categories, add these, and finally submit the product form. This is where AJAX and JQuery enter the scene.

Let’s take a look at how we can implement a pattern like this in ASP.NET MVC using the scenario mentioned above. Let me first point out that there are of course a bunch of ways you can implement this, but I’ll try to give you an example of a pretty neat implementation with a couple of benefits, along with some discussions on the way. The source code can be downloaded here.

So we need to manage products and categories. To shorten things down a bit, let’s say we already have all the basic pieces put together. We can list and create products in an ordinary fashion. When we create a new product we can select a category from a list of categories in a drop down list, but we can’t create new categories quite yet. So nothing except the basics so far (note that I’m not going through all the basics in this article, see other sources for that).

Products and categories are of course two different entities in the model. They should each have its own Controller class and of course separate views for GUI rendering, maintaining “separation of concerns”. Don’t forget the twist though, we want to evolve from the standard flow of things by making it possible for a user to add categories from the “create product” view. For clarity, let’s take a sneak peek at the final input form for adding a product and/or categories.

CreateaNewProduct

From a strict MVC viewpoint, one could argue that we have somewhat of a philosophical conflict here since we are mixing two “concerns” in the same view, namely products and categories. But luckily there are ways you can implement this and still be a good citizen. Most importantly, we need to break out the “Add new category” GUI-part (as seen in the image above) as something called a “partial view”. Think of a partial view as a slice of a page or like a user control in ASP.NET. In the process, we’ll also have to make a couple of design decisions and, of course, deal with some technical challenges as well.

So, let’s first create the “partial view” for adding a new category. This step is pretty straight forward. First, we need to create the CategoryController class with an action method that we’ll call “Create”, and that returns a PartialViewResult.

CategoryController1

Once you have created the action method, you can create the “view” by simply right-clicking somewhere inside the method and choose “Add View” from the context menu. The “Add View” dialog has an option for “Create a partial view”, which we want to do in this example.

image

In the “Create.ascx” that has now been generated for you, just add the html markup you need. Remember this is only a part of a page (again, think user control). In our case, this is where we want to create the html form for adding a new category.

CreateCategory

The next step requires decision-making. We now want to use the newly created partial view in the hosting view. Basically, ASP.NET offers two ways of doing this.

Use RenderPartial when you need to render something that naturally is a part of the hosting view and its Model (if present). You can pass the entire model or of course any subset of it, or you can choose not to pass any model at all. Examples:

<% Html.RenderPartial("partialViewName"); %>
or if you need to pass the model…
<% Html.RenderPartial("partialViewName", Model); %>

Alternatively, use RenderAction when you need to render something that naturally is not a part of the hosting view or its Model. This is the one we are going to use in this example, since adding categories doesn’t necessarily have anything to do with adding products. We just happened to realize that we wanted to host one within the other for the soul purpose of making a more efficient user interface. Example of use:

<!— Invoke the “Create” action method in the “Category” controller and render its partial view –>
<% Html.RenderAction("Create", "Category"); %>

You can find blog posts that focuses on the “one versus the other” discussion, like here or here.

The next step is to make sure that we can post the “Add category” –form and handle the return logic. This requires some server side and some client side programming. We are going to communicate with data only, through JSON (so no formatting). Before digging into server side, let’s take a look at the client side for a moment. We can either choose to go entirely with JQuery, or we can use JQuery together with some built-in Ajax helpers in the Mvc framework. Let’s go with the latter, it produces less code and makes more use of the framework we’re using. The JQuery-only approach could provide a higher level of control though, and if you are a true JQuery friend this choice could be the more attractive one. Note: The downloadable source code for this article also includes the “JQuery-only approach, hidden in a html comment at the bottom of Create.ascx.

So, we are going to use the built-in Ajax helper method “BeginForm” (in System.Web.Mvc) to create the html form. This helper renders a script in the forms “onsubmit” event that takes care of the AJAX call to our server. The new version of the Create.ascx looks like this:

CreateCategoryAjax

The first BeginForm-parameter decides the name of the action method to invoke (we haven’t implemented the action method quite yet). The second one takes an AjaxOptions object that we can fill with settings (coverage of the AjaxOptions class is out of scope for this article. For more info, go to the AjaxOptions class reference). You can use the OnComplete property to provide the name of a JavaScript function to call when the server responds.

CreateCategoryScript

This function will get called and passed a Sys.Mvc.AjaxContext JavaScript object (here named “context”). The AjaxContext object has a get_data() method that returns the JSON result that was returned from the server. First, we need to deserialize the string JSON result to a JavaScript object. For this we can use the built-in “Sys.Serialization.JavaScriptSerializer.deserialize()” method. The rest is just some code to add the new category in the drop down list, select the new category and clear the category name textbox.

On the server side we need to add the action method that the client code will invoke.

JsonCreate

To avoid any trouble, choose a different name than the (non-post) method that we just named Create earlier. If they have the same name, the RenderAction method will choose the method with the same http verb as the hosting view, and this is not always what you want. All of a sudden you could end up getting a view that tries to render pure JSON data as a GUI :) So, to take control over what action method gets used and when, the simplest way is to use unique names in these cases. However, there are also other ways to go around this issue.

That’s it, feel free to download the complete source code of course. With the helper methods of ASP.NET MVC in combination of partial views and some JQuery, there aren’t that many steps to take in order to add powerful AJAX enabled functionality to your web sites.

About these ads

4 Responses to “The power of partial views, JQuery and AJAX in ASP.NET MVC”

  1. Wei said

    Thanks, That is exactly what I want

  2. shankar said

    Hi I am using three user control inside the Begin Form
    One user control is being render by ajaxaction method and its populated means that end of the action method I used partialview of that user control.
    I want to refresh controls in other two user controls too.
    Help me in this regards.

  3. shor7.com said

    I’ve really enjoyed reading your articles. You obviously know what you are talking about! Can`t wait to read more

  4. [...] I moved that into a PartialView (.ascx) by creating a ParitialView in my Views/Shared folder (This blog post is very helpful for showing you how to use PartialViews). I called that PersonList.ascx and that is [...]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: