ASP.NET MVC: Passing model from AJAX call into a Controller – The Easy Way!

Last Friday at work, a fellow developer asked during a meeting about how to pass an object from Javascript to an ASP.NET controller. To make a long story short, I proposed a method which I believe is simple and elegant. I hadn’t used it in some time, and wasn’t clear on all the details so I took and hour (and another two to write this post) to code and present the solution.

The idea is simple, I will create a page which takes input from a user. The user can submit this data and receives a response.

First let’s state what needs to be done from a programmatic sense (in no particular order).

  1. Create a Model class to retrieve information from a user and create a Model class to respond to a user
  2. Create an ASPX page which uses this model (the project uses MVC 2 without the Razor engine).
  3. Write Javascript to handle the submission of the information, AJAX call, etc.
  4. Write the Controller to handle the AJAX call for this page.

I’ll be using jQuery and Microsoft Visual Web Developer 2010 Express to do the actual development. I’m going to assume anyone reading this can add jQuery to their project and to the web page.

Let’s get started.

Models

Below is a simple Model class which contains properties for a first name, last name, and age.

public class Info {
    [DisplayName("First Name")]
    public string FirstName { get; set; }

    [DisplayName("Last Name")]
    public string LastName { get; set; }

    public int Age { get; set; }        
}

The attribute [DisplayName()] allows me to specify what text the label tag will display. Otherwise, it will just display the name of the property in CamelCase. If you wish to use this attribute, you’ll need to include System.ComponentModel in your using statements.

Next, I can create a Model for the response class:

public class Response {
    public bool IsSuccess { get; set; }
    public string Message { get; set; }

    public Response(bool isSuccess, string message) {
        IsSuccess = isSuccess;
        Message = message;
    }
}

The property IsSuccess will be used by the Javascript to decide what to do with the response, and the Message property can be used to display some text. Of course the sky’s the limit as far as what you want to pass back to Javascript.

That completes the Model classes. I saved these both in the Models folder of the project.

ASPX Page

Now I can create an ASPX page. Well, I lied a bit. I’m actually going to create a partial view and render that in an ASPX page. Assuming you’re working with an ASP.NET MVC project. Go to the Solution Explorer. In your project you should have a folder for your Views (by default this is, in fact called Views). Wherever you wish you place the partial view within the Views folder, right click and select Add > View. You should see a dialog similar to the one below:

AjaxMVCAddPartialView

I named the view Info.ascx. Make sure the checkbox Create a partial view (.ascx) is selected and since I want to strongly this view to my model make sure the Create a strongly-typed view is selected as well. The dropdown under this labeled View data class: should point to the Info model class created above. Note that the namespace points to where I saved the Info.cs class described above.

Now that the partial view is created. I just add the mark-up to display the properties I want to show from the Info class. Below is the full ASCX file:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<JSSerializeTestMVC2.Models.Info>" %>

<fieldset id="infoForm">            
    <div style="margin: 1em .5em">
        <%: Html.LabelFor(model => model.FirstName)%>
        <%: Html.TextBoxFor(model => model.FirstName)%>            
    </div>
            
    <div style="margin: 1em .5em">
        <%: Html.LabelFor(model => model.LastName)%>
        <%: Html.TextBoxFor(model => model.LastName)%>
    </div>

    <div style="margin: 1em .5em">
        <%: Html.LabelFor(model => model.Age)%>
        <%: Html.TextBoxFor(model => model.Age)%>
    </div>
            
    <p>
        <input id="submitButton" type="button" value="Submit Info" />
    </p>
</fieldset>

Note, the model for the page (Inherts=...) is the Info class created. I used HtmlHelper class for convenient rendering of the model. I skipped using a CSS class since the example is so short but for good practice, you should generally use CSS classes instead of the style attribute. Let me point out the two important IDs. The fieldset has the ID attribute set as id="infoForm" and the bottom input tag has the ID attribute set as id="submitButton". These will both be used explicitly in the Javascript code following.

Next, this partial view needs to be rendered in an ASPX page. I’ll leave most of that to you expect to say I simply added the following line the main page (Index.aspx) I created:

<div>
     <%: Html.Partial("Info") %>
</div>

If you run the project, the partial view looks something like this:

AJAXMVCPartialView

Javascript

Below is the Javascript to handle the submit button event and the AJAX call to the controller:

$(function () {
    var submitButton = $("#submitButton");
    var infoForm = $("#infoForm");
    
    //  Attach event handler to submit button
    submitButton.click(function () {
        SubmitInfo(infoForm);
    });
});

//  Submits the Info form to Controller
//  formContainer: (jQuery) The form model to submit
function SubmitInfo(formContainer) {
    $.ajax({
        url: "Home/SubmitInfo",
        type: 'post',
        data: formContainer.serialize(),
        success: function (data) {
            if (data.IsSuccess) {
                // Clear the input tags
                formContainer.find("input[type='text']").each(function (i, element) {
                    $(this).val('');
                });
            }

            alert(data.Message);
        },
        error: function (jqXHR, textStatus, errorThrown) {
            alert(errorThrown);
        }
    });
}

There are two pieces. When the document is ready, lines #1-9 simply attach the onclick event to the submit button. This calls the function SubmitInfo and passes in the jQuery object infoForm for the fieldset. SubmitInfo simply executes and AJAX call. Note the following key/value pairs for the call. The URL is set to the SubmitInfo method of the HomeController which handles the request (we have yet to examine this). I marked the TYPE as POST. The DATA key passes the serialized jQuery object. This is the most important step to keep the code elegant. All the fields of the form will be deserialized in the Conroller as the Model class Info as we will see. Finally the SUCCESS key takes the Response class, clears the input if the returned object’s IsSuccess is true, and displays a message. For the purposes of this example, the ERROR key can be ignored.

Controller

Finally, the code for the Controller (I placed this in the HomeController):

List<Info> _contactList = new List<Info>();

[HttpPost]
public JsonResult SubmitInfo(Info contactInfo) {
    _contactList.Add(contactInfo);    // Do something with contactInfo

    var response = new Response(true, "Contact Successfully Submitted");
    return Json(response);
}

The attribute [HttpPost] disallows access to this controller except through a POST. The return value of the controller is set to JsonResult since I am returning JSON to the AJAX call (this is another key/value pair which can be set to something else, e.g. HTML).

I created a private list of type Info just for explanatory purposes. When this controller is hit by the AJAX request, it will try to deserialize the object into the type Info. Then you can do with it what you wish. Probably you’d end up doing some processing and inserting the information into a DB somehow (ADO.NET, Linq to SQL, Entity Frameworks, etc). The point is, it will be your Model. After this, I just create a Response model to send back so the Javascript can handle the submission.

Closing remarks

Certainly there is a lot more that can be said. For example, no error checking or validation is performed on the submission. To recap: The simple clean elegant way to pass a Model through an AJAX request is to serialize it. Hope this helps anyone who might stumble upon this. Below is the Visual Studio solution:

AjaxMVC.zip

P.S. – Regretfully, I have yet to post what I was referring to in the XOR post, but all in good time!

Swapping values in C#:
Tmp variable vs. XOR with performance times.

While doing a bit of coding for an upcoming post (probably the one following this) I was doing a variable swap. I started with a temporary variable swap but then decided to be cute and implement an XOR swap. As a benefit, I had the chance to remind myself how to do this (without cheating). However, I ran into an issue when I wanted to create a generalize swap function. Researching the issue, I came upon a post about how the XOR swap is not as efficient in modern architecture. Surprising! Dot Net Perls has a page about it with a link to the Wikipedia article.

As a reminder, an XOR swap can be achieved by doing the following on two variables:

int x = 1;
int y = 2;

x ^= y;
y ^= x;
x ^= y;

Console.WriteLine("x = {0}", x);
Console.WriteLine("y = {0}", y);

Output:

x = 2
y = 1

Below is the code I used to check the performance of the two methods.

int[] numbers = { 1, 2 };
int iterations = 100000000;		//Number of swap iterations
var timer = new Stopwatch();

//	XOR Swap Test
timer.Start();
for (int i = 0; i < iterations; ++i) {
	numbers[0] ^= numbers[1];
	numbers[1] ^= numbers[0];
	numbers[0] ^= numbers[1];
}
timer.Stop();

Console.WriteLine("XOR Swap time: {0}", timer.Elapsed);

timer.Reset();

//	Temporary Variable Swap Test
timer.Start();
for (int i = 0; i < iterations; ++i) {
	int tmp = numbers[0];
	numbers[0] = numbers[1];
	numbers[1] = tmp;
}
timer.Stop();

Console.WriteLine("Temp Variable Swap time: {0}", timer.Elapsed);

Here is sample output of a few runs:

XOR Swap time: 00:00:01.1918037
Temp Variable Swap time: 00:00:00.6617117

XOR Swap time: 00:00:01.1561061
Temp Variable Swap time: 00:00:00.6587373

XOR Swap time: 00:00:01.1674577
Temp Variable Swap time: 00:00:00.6651171

Of course these times vary a bit with the number of iterations and what else your computer is doing when it’s run, but I never saw the XOR swap performance beat the temporary variable. Who says bit manipulation is always faster?

Properly throwing exceptions in C#

While taking a proficiency test for a job, the following question arose (which I got wrong):

Explain the difference between

catch (Exception ex) {
	//exception handling code
	throw ex;
}

and

catch (Exception ex) {
	//exception handling code
	throw;
}

At the time, I thought they were the same so I was at a loss for an answer. The short answer is the latter preserves the full stacktrace and the former truncates it. Quite handy to know.

If repackaging the exception is necessary, then it should be passed to the new exception type like below (at least this I was already doing correctly!):

catch (Exception ex) {
	//exception handling code
	throw new MyException("A lucid exception message.", ex);     
	//MyException is of course some real exception
}

A good explanation can be found at Scott Dorman’s blog.