×
Get in touch

Get in touch with Binary

Binary Studio website uses cookies to enhance your browsing experience. By continuing to use our site, you agree to our Privacy Policy and use of cookies.

Learn more more arrow
Agree
Kateryna Semenista Ex-COO 22.04.2010

Building a custom JSON web service with ASP.NET MVC


This article describes how to build JSON service based on ASP.NET MVC application. Also here you can see example of advanced routing based on web-forms. Error-handling for almost all errors included.

Part I:  Routing, request verification and error handling

Description and requirements

As you know, we do a lot of .NET development here at Binary Studio. We had a task to create JSON service based on posted web pages which corresponds to specified format. Purpose of this task was to connect some legacy sites to one network with single data storage. Corresponding to that we have already /*specified*/ protocol specification.

Request specification:

Calls to service were implemented as posted web form requests with specified HTTP headers:

HTTP Reader Description Example
Content-Type Query type - form parameters form-data
Site Name of site, where request come from, some sites can have different methods test-site.com
Request-Timestamp Query sending time 25.10.2009 16:47:07

Web service should be able to detect request forgery. Here in the article we'll use a simplified check: timestamp should not differ from current server time more than specified time. Default value- one minute.

Request parameters passes as POST parameters as multipart/form-data.

Name of service call method passes as post parameter named "call"

User identifier (in DB) passes as parameter "user"

Other site always waiting for result returned as JSON object with two fields:

  • "Error" (string) –contains error messages
  • "Result"(object) – contains response data

As you can see, we have such tasks:

  1. Creating route based request on form parameters and HttpHeaders
  2. Validate request
  3. Return data in specified JSON format, even if request was wrong or something happens on server (of course, if server not down 🙂

And additional requirement:

4. Good test coverage, which allow us to check everything before server will go to production (this should be “hot replace”)

I will describe how we solved first three tasks here. The test story will be covered in the next article.

We found an elegant solution for this task with ASP.NET MVC.  It has everything we need:

  1. Good routing customization
  2. Ability of request headers parsing and automatically pass this data to controller methods
  3. Additional modules, which can be added on different stages of request processing
  4. Easy  work with  JSON

Advanced routing and parsing form data

I start from solving our first problem: We needed to route not standard http request, which have fixed URL, but pass needed params from headers and form data. As I already told, MVC has good routing possibilities and we need to add our custom route there. We will take data from HttpContext.Request, it has all needed data already parsed and stored in collections. HttpHeaders we can get from

and  form data with

Сreation of our custom routing  will take 2 steps:

1. Create custom route class which get request data and put it to “controller” and “action”. Just add this class to Global.asax

2. Add our new class to RegisterRoutes method in Global.asax:

As you can see, MVC routing is a powerful tool which allows you not only configure url as you want, but handle more difficult cases like http headers, form data and whatever you need.

Request validation

Next thing we do is request validation. For that purpose we used custom HTTPModule, which allowed us check request and return error messages (if needed) even before routing.

This task can be solved in two steps too:

1. Create class of http module. Http modules are a powerful tool, which will allow you to catch a lot of application events.

This class binds to BeginRequest event handler. Now we can check our request at first stage (even before routing). We just get http header from request, as we do that in routing, and verify data as we want

2. We need to register module in web-server. Add this string to <HttpModules> section in Web.config

Now every request to your site will be checked before processing. This can be useful if you need to build highly loaded sites protected from unauthorized access.

Error handling

Our third task was to return answer even if service returns error. Of course, we could write every method with error handling, but this way produces big bunch of code, which is not very good for support. Instead of this we have made handler, which get lambda expression, process it and handles errors

Now our controller methods use lambda expressions and look like this

It just a little more difficult than usual.

We can add a little improvement, that allow us to write more simple code. This method returns object wrapped as JsonResult

Add it to your controller, and write:

Now we can handle all errors in service methods, but still have a hole: What will happen if wrong params will be passed to method? Or how we handle any other error? For that purpose we can create two  walls of error handling:

  1. OnException method in controller
  2. Application_Error method in MvcApplication (in Global.asax)

Often error can happen when method parameter name or type don’t matches with passed in request. For that purpose we can override OnException method in controller. Our implementation catches ArgumentException, return standart error message and log detailed information:

At last stage we should handle all other errors which can happen in our server. Easiest way to do this is to add Application_Error method. We don’t have JsonResult here, so we should write answer manually. Note, that I set StatusCode and StatusDescription to “200 OK”, it helps us to return normal answer in all cases (even if you have 404 or 500 error)

So, what we have in result? We have web application, that applies to all our requirements.

You can dowload sample solution here.

Denis P., .NET team,
Binary Studio