JQuery is an amazing Javascript library.   If you haven’t used it yet, you are REALLY missing out.  This article is going to talk about how you can use JQuery to make an AJAX call from an MVC application, and how you can receive JSON rather than XML from the web service.

First we’ll deal with the why.  Why would we want to receive JSON rather than XML to our web service?  To me, the answer to that starts with the fact that if we’re making an AJAX call, we’re going to do something with the results in client code.  It makes sense to use a format that is inherently understood by Javascript, which is what the client code is going to be written in most of the time.  The fact that we can send JSON data to our .NET web service allows us to pass objects back and forth from .NET and Javascript easily.

Our use case is going to be relatively simple, I want to be able to add a user to our database from an HTML form, and update the user interface when the task is done asynchronously.  I have a sample database with a very simple user table set up for this example.  I created a .dbml file with LINQ to SQL for my data layer:

data 

I created an index view for my form, the code looks like this:

<fieldset>
    <legend>Enter User Information</legend>

    <p>
    <label for="FirstName">First Name</label>
    <input type="text" id="FirstName" />
    </p>

    <p>
    <label for="LastName">Last Name</label>
    <input type="text" id="LastName" />
    </p>

    <p>
    <label for="Email">Email</label>
    <input type="text" id="Email" />
    </p>

    <p>
    <label for="Phone">Phone</label>
    <input type="text" id="Phone" />
    </p>

</fieldset>

<br />

<div class="buttons">
    <button type="submit" class="positive" name="save" id="btnSave">
        <img src='<%= Url.Content("~/Content/Images/apply.png") %>' alt=""/>
        Save
    </button>
</div> 

<br /><br />
<div id="result"></div>

The div at the bottom is where I plan to show if my service call was successful or not.  One thing I did here was use a tip I picked up by Dave Ward at Encosia.com and make the ID’s of my inputs match the property names on my user object.  This makes life easier on us later.  Then, to fix up the look and feel of the site a little, I just add a little CSS:

fieldset {
    border: 1px solid #226078;
    background: #62B1D0;
    width: 320px;
    padding: 2px;
}
fieldset legend {
    border: 1px solid #226078;
    font-family: Tahoma;
    font-size: 9pt;
    font-weight: bold;
    background: #0776A0;
    color: #FF8500;
    padding: 6px;
}

label {
    display: block;
    float: left;
    font-family: Tahoma;
    font-size: 8pt;
    font-weight: bold;
    color: #024C68;
    width: 150px;
}

label:after { content: ": " }


This makes my end UI look (slightly) more presentable.  I know, you envy my crazy user interface skills.

interface

The next thing to do is set up the JQuery code so that our button click even sends an asynchronous request to the web service.

<script language="javascript" type="text/javascript">
    $(document).ready(function() {
        $("#btnSave").click(function(event) {
            var user = {};

            // Use JQuery to iterate over the text fields and build the object.
            $(':text').each(function() {
                user[this.id] = this.value;
            });

            // Create a data transfer object (DTO) with the proper structure.
            var DTO = { 'user': user };

            $.ajax({
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: "DataService.asmx/AddUser",
                data: JSON.stringify(DTO),
                dataType: "json",
                success: function(result) {
                    if (result.d)
                        $("#result").html("<span style='color:#529214'>User added successfully.</span>");
                    else {
                        $("#result").html("<span style='color:#d12f19'>Operation failed.</span>");
                    }
                }
            });
        });
    });
</script>


In the above code, you will see why we named the textboxes the same as the user object properties.  I used the JQuery each construct to loop through all the text boxes and populate the user object.  This is a much cleaner way to populate the object than manually setting every property.  The ajax call is pretty straight forward, I’m using the stringify method in the json2js library to turn my string into valid JSON, and lastly I’m wrapping my user object in a data transfer object to make the client code a little cleaner.  (another tip from Dave Ward)  On success of the asynchronous call, I’m parsing the result to determine whether the user was added successfully or not. 

Since I used LINQ to SQL to generate my objects, I decided to make it easy on myself by adding the “add user” logic in a partial user class.

public partial class User
{
    public void Add()
    {
        var db = new BlogSamplesDataContext();
        db.Users.InsertOnSubmit(this);
        db.SubmitChanges();
    }
}

The last step is to create a web service called DataService.asmx with a web method called AddUser that takes a parameter called user.

[System.Web.Script.Services.ScriptService]
public class DataService : WebService
{
    [WebMethod]
    public bool AddUser(User user)
    {
        try
        {
            user.Add();
        }
        catch (Exception ex)
        {
            // Error logging can happen here.
            return false;
        }

        return true;
    }
}


Make sure you uncomment the line in the web service that allows the service to be called from scripts..for whatever reason I forget to do that a lot.

I was trying to walk the line between “simple enough to get my point across” and “complex enough to show value” for this example.   The key is that you can pass full objects from client code to .NET web service code with the use of JSON, and you can make asynchronous calls to web methods fairly easily using JQuery.

kick it on DotNetKicks.com