JSON web services when you’re stuck in with basic ASP.Net…

Whilst it’s nice and easy to create JSON services for your front-end JavaScript if you’re working in ASP.Net MVC, things can be a bit more difficult to wire together if you find yourself with project requirements that force you to work with the older bits of ASP.Net. Getting the JSON inputs and outputs to work can caused me some head-scratching.

Having had to make this work recently, I thought I’d write down where I ended up after searching Stack Overflow and MSDN…

Setting up a simple service

When you try to add an item to a simple ASP.Net web project to implement a JSON service, there’s quite a lot of choice:

Add new item form

The simplest type to choose for is the classic “Web Service” – which generates you an ASMX file. While these default to being SOAP web services, we can give them some simple configuration to make them work with JSON. (As long as you’re using .Net 3.5 or newer) And they also don’t need any fancy configuration in the web.config – which is a bonus come deployment time.

When you create a new service you get a code-behind file that looks like this:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
// [System.Web.Script.Services.ScriptService]
public class JSONService : System.Web.Services.WebService
{
    [WebMethod]
    public string HelloWorld()
    {
        return "Hello World";
    }
}

To get JSON into and out of your service, you need to make a few changes to attributes on the class and on any methods you create. The ScriptService attribute mentioned in the comments can replace the two WebService related ones. And the ScriptMethod attribute needs adding to each method you create along with the WebMethod:

[System.Web.Script.Services.ScriptService]
public class JSONService : System.Web.Services.WebService
{
    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public string HelloWorld()
    {
        return "Hello World";
    }
}

The ResponseFormat property for the ScriptMethod attribute is what we need to get JSON as a return value.

Exchanging JSON

So now you’ve got a method, what do you need to do to exchange some JSON with your front-end scripts?

Well on the server side, it’s fairly easy – much as you would do in an MVC project. You can just define some classes to represent your input and output data structures, and the magic in the WebService class will deal with trying to convert your data to and from JSON.

For example, you can create a quick test method like so:

public class Input
{
    public string Name { get; set; }
    public int Number { get; set; }
}

public class Output
{
    public string Message { get; set; }
    public List<int> Result { get; set; }
}
    
[System.Web.Script.Services.ScriptService]
public class JSONService : System.Web.Services.WebService
{
    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public Output Process(Input input)
    {
        Output o = new Output();

        o.Message = "Hello " + input.Name;
        o.Result = Enumerable.Range(0, input.Number).Select(i => i * 2).ToList();

        return o;
    }
}

The input data type contains a string and an integer, and the method processes the string and turns the integer into a list of integers. Nothing exciting or clever – but enough to demonstrate what’s possible.

Then we need some script to call the service. This is based on jQuery’s Ajax framework:

<script type="text/javascript">
    $(document).ready(function () {

        var inputObject = {
            Name: "Tester",
            Number: 5
        };

        $.ajax({
            url: "/Search/JSONService.asmx/Process",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            data: JSON.stringify({input: inputObject}),
            dataType: "json",
            success: function (data) {
                var output = data.d;
                alert("Message: " + output.Message + "\n" + output.Result);
            }
        });

    });
</script>

The input data is a simple Javascript object here, with properties using the same names and types as the C#.

Then we need to set up the Ajax call. The first four properties we need to set are to do with sending data to the server:

  • The URL to call is the URL of your ASMX file, with the method name appended to the end.
  • The operation type being used to send the data here is a HTTP Post.
  • The content type for the data we’re posting is JSON.
  • And finally the data itself needs to be passed as JSON.

For the data property here, we need to do two things. Firstly, the object we send to the server needs to have the right property name to match the parameters of the server method. Hence the data we’re sending is {input: inputObject} – wrapping the parameters we’re sending correctly so that the web service can work out how to map the data to the method we’re calling.

And then we need to make sure that the data we send is JSON. The easiest way to achieve this is with the JSON.stringify() method. Modern browsers support this natively, and it turns any plain Javascript object passed in to a JSON string.

However it’s worth noting that if you’re using an older version of Sitecore and you need to support Internet Explorer for editors then this method can cause a problem. If your editors need to have Compatibility Mode enabled for the website you’re builfing then JSON.stringify() does not work. IE still claims to support it, but it doesn’t function.

If you need to work around this, then you should add a script reference to JSON2.js. This gives IE the ability back again, and works with or without Compatibility Mode.

And then the remaining two properties of the Ajax request are for receiving data:

  • The dataType property says you expect to get JSON back from the server.
  • And the success property lets you handle a successful result.

Obviously, you probably need to handle unsuccessful results as well…

The data object that your server code returned comes back to the success callback in the d property of whatever you call the parameter to your callback. But after that it’s just a plain object with the same properties as your server object. For example, the result coming back from this call looks like:

Object

So with that code you can cover a lot of client-to-server calls.

It’s worth noting that while the JSON serialised that ASP.Net is using is pretty good, you still have to be careful about how you represent objects to send them from the client to the server. You can get 500 errors from your service when it fails to massage your JSON into .Net data structures.

I found the easiest way to work out what JSON the ASP.Net code is expecting to receive is to write the C# data structure you want to populate, fill in its properties, and then send it from the server to the client in a test message. That allows you to use your browser’s debugger to look at the object which arrives on the client. And that’s the structure you need to repeat in your client-side code.

Now to do something more interesting with this…

Advertisements

One thought on “JSON web services when you’re stuck in with basic ASP.Net…

  1. Pingback: Updating faceted search with client-side code | Jeremy Davis

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s