Monday, 10 November 2008

Asynchronous Data Loading in ASP.NET MVC Components

I recently came across a problem when designing my ASP.NET MVC enterprise application where I needed a user control to hit the database to load some information dynamically without refreshing the page.  I did a bit of searching and found a few possible ways of doing it, but when I asked the question on Stack Overflow I got a great answer.

The example uses jQuery, if you’re not familiar with it try this site as I found it quite helpful.  Your controllers are not restricted to returning views only, action results can be in the form of Json data if you wish or many other types of data.  Using System.Web.Mvc you can find the JsonResult action result.

If we call an action that returns a JsonResult from an Ajax control using java script we can asynchronously get the data we need and not have to worry about postbacks on the page.

For my example I’m going to do almost exactly the same as my answer from stackoverflow, but I found a few things that didn’t work for me so I’ll repair them.  I want a text box to auto complete.  When I type the first letter I want it to fill out the remainder for me and select the whole text.

My action looks something like this

public ActionResult GetSuggestions(string searchText)
    return Json(new { SearchText = searchText + "completestring"});

No checking of the database here, it’s out of the scope of this post, just return the letter or letters entered and add “completestring” to the end. 

Now all I need to do is use some javascript inside my HTML link so.

function startAutoComplete() {
    var searchText = $("#inputText").val();
    $.getJSON("/Search/GetSuggestions?searchText=" + searchText, null, autoCompleteResponse);
function autoCompleteResponse(data) {
    if (data.SearchText) {

This code will input component called inputText and set the value of the text box to the output of the JSON based action.  The data is returned via an event handler (autoCompleteResponse(data)) so that it is handled asynchronously.

This example is the simplest use case I could think of, and it’s not terribly useful.  But this same method is going to be very useful for me when searching for data to complete entry fields (user search for a user field for example) and when creating other asynchronous components.