This morning, I jumped in to help out my friend Julie Lerman with a question about using jQuery with ASP.NET WebAPI. In my mind, that's easy... something I've wired up lots of times and shouldn't be a problem. I offered to pair program for a bit and take a look at the code, after all... how hard could it be?
This was an interesting and simple block of jQuery that was expecting JSON from a service. A simple WebAPI controller, similar to the one we were attempting to query looked a little like this:
public class ValuesController : ApiController
{
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
That's easy to get data from with jQuery, I can use an AJAX call to get the data from my server with JavaScript like the following:
$.ajax({
url: "http://localhost:64948/api/values",
type: 'GET',
dataType: 'json'
}).done(function(data) { alert(data.length); });
When I run this page from the same server that is hosting my service, no problem. I get a simple alert box with the number 2.
That Wasn't Our Problem.
In this scenario, Julie was querying a different server that was hosting WebAPI and needed the services of JSONP to make that cross-origin request. The jQuery documentation indicates that you can simply switch the dataType
of your AJAX call to "JSONP" and everything will just work.
No dice... nothing. We poked and prodded that JavaScript code and got nothing from it. Then it hit us: the problem isn't the JavaScript, it's the callback coming from the server. WebAPI needs to know how to issue a command back to our script.
To complete the task and get WebAPI responding properly to a JSONP request, install the JSONP MediaTypeFormatter from NuGet. Once that is installed, enter your App_Start\WebApiConfig.cs and add to the bottom of the Register
method the following line:
GlobalConfiguration.Configuration.AddJsonpFormatter();
Rebuild and re-run the JavaScript and now the done method of the AJAX call is being executed.
We were happy, and all was right in the world.
What Did We Learn About this Problem and How to Write Better Software?
The short answer is: JavaScript development is REALLY HARD without proper error messages and with connections that fail silently. There was no indication that the WebAPI was not attempting to call the Done
callback method from jQuery. Additionally, WebAPI wasn't throwing any warning message to indicate that there were arguments passed in that it didn't know what to do with. This lack of verbose messaging in a debugging environment made it difficult for two experts to be able to track down a problem.
How would an average developer handle this? We can do better... I'll write more about this approach to making debuggable (yea, I just invented that word...) software tools next time and how we can improve this experience.