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!

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

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>