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.