Articles

Ajax User Controls in ASP.Net MVC Preview 3

In .Net on July 29, 2008 by Matt Grande Tagged: , , , ,

I was taking a look into how to ajax up my website using the new ASP.Net MVC stuff, and I came across some difficulties. After using Ruby on Rails for the better part of the last year, I expected to be able to call render_to_string or something similar on a UserControl, and replace a div with that string.

I’m writing a basic product page, and the product can come in many colours. I opted to ajaxify the colour pagination.

The first thing I did was get JQuery into my project. JQuery is a javascript library that makes a lot of the more common AJAX and DHTML tasks easier.

function ChangeColorwayPage(pageNumber) {
  // Hide the element with the id of colorway1
  $("#colorway1").hide("slow");
  // Generate the URL of the ajax call
  url = '/ColorWay/ChangeColorWayPage/<%= ViewData.Model.Style_Number %>/' + pageNumber;
  // Make a GET request to the URL.  The third parameter is the function that gets called after the ASP.Net code is run.
  $.get(url, null, function(data, status) {
    // Replace the HTML within the div 'colorway1'
    $("#colorway1").html(data);
    // Show the div again!
    $("#colorway1").show("slow");
  });
}

This was easy enough. The tricky part came when rendering a UserControl into a string. I opted to make a simple AjaxController that inherits from the base Controller object.

namespace YourApp.Controllers
{
    public class AjaxController : Controller
    {
        public string RenderToString(string UserControl, object model, Dictionary<string, object> ViewParameters)
        {
            // Replace the current context with a new context that writes to a string writer
            var existingContext = System.Web.HttpContext.Current;
            var writer = new StringWriter();
            var response = new HttpResponse(writer);
            var context = new HttpContext(existingContext.Request, response) {
                User = existingContext.User
            };
            System.Web.HttpContext.Current = context;

            // Add the ViewParameters to the ViewData hash
            foreach (string key in ViewParameters.Keys)
                ViewData[key] = ViewParameters[key];

            // Execute the action
            var viewResult = View(UserControl, model);

            // Execute the result
            viewResult.ExecuteResult(ControllerContext);

            // Restore the old context
            System.Web.HttpContext.Current = existingContext;

            return writer.ToString();
        }
    }
}

And now, in my ColorWay controller, all I have to do is this:

namespace YourApp.Controllers
{
    // Notice that it inherits from AjaxController
    public class ColorWayController : AjaxController
    {
        public string ChangeColorWayPage(string sellingStyleNumber, int pageNumber)
        {
            var productSpecs = new ProductSpec(sellingStyleNumber, false);
            var parameters = new Dictionary<string, object>();
            parameters["page"] = pageNumber;

            // Simply call RenderToString and you're good to go!
            return RenderToString("ProductSpecColorWay", productSpecs, parameters);
        }
    }
}

And with that, you should be good to go.

Happy coding!

Advertisements

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

%d bloggers like this: