Posting Data With jQuery AJAX In ASP.NET Razor Web Pages

There have been a few questions recently about what you can post to the server using jQuery AJAX and where to find whatever you posted. This article looks at using the jQuery ajax method in ASP.NET Razor Web Pages and explores how different options have different results.

The first thing to look at is the key settings options that are available for AJAX requests:

type This is type of HTTP Request and accepts a valid HTTP verb. POST is the option illustrated in this article.
url This is the location of the resource that the request will be made to.
data This is the actual data to be sent as part of the request.
contentType This is the content type of the request you are making. The default is 'application/x-www-form-urlencoded'.
dataType This is the type of data you expect to receive back. Accepted values are text, xml, json, script, html jsonp. If you do not provide a value, jQuery will examine the MIME type of the response and base its decision on that.

This information is provided at the jQuery site (http://api.jquery.com/jQuery.ajax/) and what is detailed above doesn't add to the official documentation. However, most issues that I have seen relating to jQuery POST requests seem to result from a lack of understanding about how these settings actually work.

You can post a range of different data types including form values, arrays, JavaScript objects and JSON. First, it is important to clarify that JavaScript objects and JSON are not the same thing. A JavaScript object is a data type with properties and values. A simple one is represented in JavaScript as follows:

var car = { Make: 'Audi', Model: 'A4 Avant', Colour: 'Black', Registered: 2013 };

The syntax is almost identical to the way that you declare an anonymous type in C# - just lacking a new in front of the opening brace and replacing the = with colons. But there are other ways to declare a JavaScript object. Unlike C#, JavaScript object properties can be strings as well as identifiers:

var car = { "Make": "Audi", "Model": "A4 Avant", "Colour": "Black", "Registered": 2013 };

This potentially leads to the confusion between JavaScript objects and JSON, which is a string representation of data. The JSON representation of the car object is syntactically identical:

{"Make":"Audi","Model":"A4 Avant","Colour":"Black","Registered":2013}

But JSON is a data interchange format which has a number of rules: the properties must be enclosed in double quotes being one. For that reason, and to reduce confusion, I tend to avoid using quotes around property names in JavaScript objects. Other differences between JavaScript objects and JSON include support for data types: JSON does not yet have an accepted standard for representing datetimes, for example.

Whenever any request is made to an ASP.NET application, the raw content of that request populates the Request.InputStream property. You can access this raw data by using a StreamReader:

string input;
using(var reader = new StreamReader(Request.InputStream)){
   input = reader.ReadToEnd();

}

If the request content is formatted using a standard encoding such as application/x-www-form-urlencoded, ASP.NET will parse the response for you and populate the Request.Form collection with the name/value pairs taken from the InputStream as a convenience.

Posting JavaScript Objects

When the contentType of an AJAX request is set to application/x-www-form-urlencoded, jQuery will convert the property names and values of a JavaScript object to a query string and url-encode it. The following example POSTs the car object from above:

<script>
   $(function () {
        $("button").click(function () {
            var car = { Make: 'Audi', Model: 'A4 Avant', Colour: 'Black', Registered: 2013 };
            $.ajax({
                type: "POST",
                url: "/Receiver",
                data: car,
                datatype: "html",
                success: function (data) {
                    $('#result').html(data);
                }
            });
        });
    });
</script>

In the example above, the contentType has not been set so the default application/x-www-form-urlencoded will be used. The dataType option has been set to html, which states that I am expecting the "Receiver" page to return some HMTL to me. If all goes well with the request, the returned HTML will be plugged in to an element with the id of "result". Here's the code for the Receiver.cshtml page:

@{
    string input;
    using(var reader = new StreamReader(Request.InputStream)){
        input = reader.ReadToEnd();
    }
}
<div>
    <h3>Input Stream</h3>
    @Server.UrlDecode(input)
</div>
<div>
    @if(Request.Form.Count > 0){
        <h3>Request Form</h3>
        foreach(string item in Request.Form){
            <div>@item  :  @Request[item]</div>
    }
}
</div>

The code does two things: it outputs the InputStream to the browser, having urldecoded it, and it iterates the Request.Form collection, outputting any name/value pairs it can find there. The result from posting the car object looks like this:

So if you want to post a JavaScript object via jQuery, pass the plain object to the data option, and leave the contentType option alone. The default option is perfect. Then you can access the property values of the object in the Request collection as if you have posted a form.

Posting JavaScript Arrays

If you want to post an array via jQuery, you need to do two things. You must provide a name for the array, and you need to leave the contentType as the default value of application/x-www-form-urlencoded:

var ids = [1, 2, 3, 4, 5];
$.ajax({
    type: "POST",
    url: "/Receiver",
    data: { myArray: ids },
    datatype: "html",
    success: function (data) {
        $('#result').html(data);
    }
});

Here's what the Receiver page returns:

jQuery uses the name of the array as the key and serialises all array elements with the same key - although interestingly, jQuery adds square brackets to the key value: myArray[]. As far as ASP.NET is concerned, when the request is processed on the server, it is the same as a radio or checkbox group. ASP.NET populates the Request.Form collection with one name/value pair - the name being the key that was generated by jQuery and the value being the array values as a comma-separated string. You can process them by using string.Split:

@foreach(var item in Request["myArray[]"].Split(new[]{','})){
    // do something with item
}

Posting Form values

I have seen examples of people constructing a JavaScript object out of form values and then posting the result and I am sure there are occasions when it makes sense to do just that. However, in the majority of cases, using the serialize() method is sufficient. This takes the values of the specified elements and serializes them to a query string. Here's a simple form:

<form id="myForm">
    <div>
        @Html.Label("First Name", "firstname") 
        @Html.TextBox("firstname", "Mike")
    </div>
    <div>    
        @Html.Label("Last Name", "lastname") 
        @Html.TextBox("lastname", "Brind")
</div> <div> @Html.Label("Gender", "gender") @Html.RadioButton("gender", "male", true) Male @Html.RadioButton("gender", "female") Female </div> </form>

Notice that there is no submit button within the form tags. The button lies outside, so it won't submit the form by default. This is all that's needed in the button click event handler:

$.ajax({
    type: "POST",
    url: "/Receiver",
    data: $('#myForm').serialize(),
    datatype: "html",
    success: function (data) {
        $('#result').html(data);
    }
});

The serialize command is called on the form element as a whole, which means that all form fields will be included in the request, and again, the contentType is not specified so it falls back to the default application/x-www-form-urlencoded. The result is as below, and is identical if a JavaScript object had been posted with the same properties and values.

Posting JSON

As I touched on earlier, there is nothing magical about JSON. It is just a data interchange format where values are converted to a string. The format has certain rules that must be followed, and these rules make is easy to create parsers. Why would you use JSON? Well, for one thing, it is much easier to represent a complex object in JSON and to let parsers unpick it on the server. If you posted a complex object using the application/x-www-form-urlencoded format, you would have to parse the response yourself to reconstruct the object on the server. ASP.NET includes some API's for deserialising JSON to objects on the server, including the Json helper for Web Pages.

How do you create JSON? Most browsers these days include the JSON.stringify method, so that is the recommended way:

var car = { Make: 'Audi', Model: 'A4 Avant', Colour: 'Black', Registered: 2013 };
$.ajax({
    type: "POST",
    url: "/Receiver",
    data: JSON.stringify(car),
contentType: "application/json",
datatype: "html", success: function (data) { $('#result').html(data); } });

On this occasion, the contentType is set to application/json. The dataType is still set to html, since that is the data type of the response I am expecting from the server. And this time, the response shows that the Rsequest.InputStream is the only place where I can get at the posted data on the server.

If I am happy to work with dynamic objects, I can use the dynamic version of Json.Decode on the server to convert the JSON to something I can work with in C#:

@{
    string json;
    using(var reader = new StreamReader(Request.InputStream)){
        json = reader.ReadToEnd();
    }
    var car = Json.Decode(json);
}

Or if I prefer to work with strongly typed objects, I can use the version that takes a type parameter:

@{
    string json;
    using(var reader = new StreamReader(Request.InputStream)){
        json = reader.ReadToEnd();
    }
    var car = Json.Decode<Car>(json);
}

Posting values via jQuery can be confusing at first, but as this article attempted to show, once you have an understanding of the different data types that you can post, and the purpose of the contentType and dataType options, things become a lot clearer.

 

Date Posted:
Last Updated:
Posted by:
Total Views to date: 162708

17 Comments

- Joe

Is it possible to implement ajax form in Web Pages.. like
Simple contact form without refreshing?

- Mike

- Sangeetha Naikr

Is it possible to implement ajax form in Web Pages.. like
Simple contact form without refreshing?

- Mike

@Sangeetha

Yes. You can adapt the code I featured in this article on MVC forms: http://www.mikesdotnetting.com/Article/106/A-Degradable-jQuery-AJAX-Email-Form-for-ASP.NET-MVC

- VISHAL

g8 JOB sIR :)

- wazz

great info!!

- Satyabrata Mohapatra

Excellent article!!
These ads in the middle of the article are really disturbing.

- Mike

@Satyabrata,

It's kind of an experiment. It's unlikely to be permanent.

- Marty

Great article. You don't show the code in Receiver.cshtml to send data back. How would you send text data for instance as an argument to a callback function for the JavaScript to process?

- Mike

@Marty,

Your receiver page will process the post and then just render the text to the browser.

- Marty

Mike, what if I don't want to render back the text to the browser, but I want to send it some other JSON data which the JavaScript can act on? Is there an easy way to return JSON data from a cshtml page back to the JavaScript?

- Mike

@Marty,

You should read this article: WebMatrix - Working With The JSON Helper

- Marty

Mike, you're the Man! Another great article. So incredibly helpful. I'm definitely going to buy your book - Beginning ASP.NET Webpages. Thanks for all of the great and practical info.

- Justin Kusuma

Hi Mike, thanks much for sharing such an article :)
Really help me a lot...
further, I'd like to know how to provide feedback for user after the receiver page has finished process the data..

- Mike

@Justin

You can add your feedback function to the success callback e.g.

success: function (data) {

$('#result').html(data);
alert('Success');
}

- Dome

Hi, I've just created a new project with WebApi & MVC, then created a controller with the following code:
http://pastebin.com/JpiDpJbW
but Visual Studio is telling me "Reuquest" doesnt have an attribute "InputStream" .. I've double checked References & Using's but even if I add "using System.Web.Mvc;" it doesnt change.

- Justin Kusuma

Hi Mike, thanks for replying...
I'm looking for more elegant way to provide user feedback.
As now I've tried using bootstrap 3 alert.
But as for the data updates in datatable, i still haven't figured the better way to sync the updates without full postback

Recent Comments

sandeep 8/28/2015 7:03 AM
In response to 7 C# 6.0 Features That Every ASP.NET Developer Should Know About
very good article, i like it........keep writing such quality article in future. thx Mike....

Hassan, MVC Learner 8/28/2015 6:37 AM
In response to Get The Drop On ASP.NET MVC DropDownLists
Great Help, simple, great and patiently explained article !...

Anvesh 8/28/2015 12:39 AM
In response to ASP.NET MVC DropDownLists - Multiple Selection and Enum Support
what if we are taking postback values from FormCollections instead of an array int[] category. How...

Ben 8/27/2015 10:50 PM
In response to Simple File Download Protection with ASP.NET
Is it possible to setup your project to publish files to outside of your root directory? I would to...

Fred 8/26/2015 12:50 AM
In response to WebMatrix Opens Wrong Version Of Visual Studio
I enjoyed many of your tutorials but the problem is none of the tutorials are combined like most be....

Muhammad Ashikuzzaman 8/25/2015 2:48 PM
In response to Managing Checkboxes And Radios In ASP.NET Razor Web Pages
That's a very good tips for razor...

Sergey 8/25/2015 8:32 AM
In response to More Flexible Routing For ASP.NET Web Pages
Hi. How I can set up my site to get urldata from link for default page? site.com/default/1-...

Tony Gray 8/25/2015 6:27 AM
In response to Adding Validation
Hi Mike, Really helpful article and series. Thanks. Small typo in 4th paragraph you have so...

amanda n 8/25/2015 12:38 AM
In response to Solving the Operation Must Use An Updateable Query error
Thank you very much. I'm a uni student and while solving coding problems is usually enjoyable and me...

salman 8/23/2015 9:25 AM
In response to How To Send Email In ASP.NET MVC
thanks ......