65.9K
CodeProject is changing. Read more.
Home

Call .NET WebAPIs using matching JavaScript functions - JSRPC.Net

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (3 votes)

Sep 8, 2012

CPOL

2 min read

viewsIcon

16810

downloadIcon

142

JSRPC.Net creates a JavaScript object with functions to call your WebAPI.

Introduction

Microsoft's new MVC 4 has a great new feature, WebAPI (tutorial), that makes returning data (instead of an ActionResult) much easier. There's a bit of room for improvement, however. The problem and solution is easiest to see with a side-by-side comparison. First, some code with stock MVC 4:

class DataTransferObject
{
    public int left{get;set;}
    public int right {get;set;}
}
 
class ExampleController : ApiController
{
    [HttpPost]
    public int Add(DataTransferObject dto)
    {
        return dto.left + dto.right;
    }
}

And to access it from JavaScript:

var result;
var dto = new Object();
dto.left = 3;
dto.right = 5;
$.ajax({
    cache: false,
    async: false,
    type: "POST",
    url: "/api/Example/Add",
    contentType: 'application/json',
    dataType: "json",
    data: JSON.stringify(dto),
    success: function (receivedData) { result = receivedData; }
});

This is not a very elegant solution for what is essentially nothing more than a remote procedure call (RPC). Now for the same thing, using JSRPC.Net:

public class ExampleController : JSRPCNet.ApiController
{
    [JSRPCNet.ApiMethod]
    public int Add(int left, int right)
    {
        return left + right;
    }
}

And the corresponding JavaScript:

var api = new JSRPCNet("/api/Example");
alert(api.Add(3, 5));

Or, asynchronously:

var api = new JSRPCNet("/api/Example");
api.AddAsync(3, 5, function (result)
{
    alert(result);
});

Using the code 

  • Instead of using System.Web.Http.ApiController as the base for your API classes, use JSRPCNet::ApiController as shown above.
  • Also, mark API methods with the [ApiMethod] attribute, instead of HttpPost.
  • Ensure that the controller class name ends with Controller, but exclude it from the API URL.
  • The routing string must be: "api/{controller}/{action}/{id}".
  • The api part is not actually required, so long as the API URL you use is correct. 
  • Reference JSRPCNet.js from your .cshmtl wherever appropriate. 
  • If possible, keep a copy of the constructed JSRPCNet object in JavaScript, to improve performance. 
  • Each JavaScript function has an async equivalent that takes a function object as its last parameter.  

Points of interest  

The class JSRPCNet::ApiController has a post method called GetAPI. When calling the new JSRPCNet(apiURL) in JavaScript, it uses this method to retrieve a listing of [ApiMethod] methods and their parameter names, and builds the JavaScript functions using the received data. Some things to note: 

  • JSRPCNet::ApiController caches compiled API information and late-bound methods to improve performance.
  • All API calls are performed using POST.
  • The parameters may be primitive types or complex types - anything that can serialized and deserialized as JSON. 

Some technologies that make it all work:

  • .NET's Reflection
  • Expression trees to compile late-bound dynamic calls, so calls are fast
  • JSON.Net and C#'s dynamic keyword.
  • MVC4's WebAPI.
  • jQuery's $.ajax function.
  • LINQ to manipulate data collections 

History

  • 8/29/2012 - Initial upload.