Welcome to the "Web API with AJAX" article series, here we have been explaining various concepts related to AJAX and the Web API that is the latest technology for Microsoft's communication platform. We have explained RESTful services and various ways to consume it using the ajax() function. You can read the complete article here.
In this article we will learn to handle exceptions in the Web API. I hope this article will help you in your day to-day programming life and programmers will able to implement the concept in their application. So, let's start our explanation.
We know that exception handling is very very (yes, 2 times; not a mistake) important concept in any application. The common misconception of the novice programmer is that, "a good programmer's code never throws an exception" But this is not true at all. A good programmer's code handles exceptions efficiently and no one knows when an exception will be raised.
So, we cannot prevent exceptions but we can handle exceptions. When the code is in the same environment, in other words within the same AppPool or Sandbox then the exception handling is easier. But if the application is service-oriented and if an exception is thrown from the service then the mechanism for handling the exception is different.
Let's try with traditional approach
In this example we will try to handle an exception in a traditional way, in other words within a catch block we will catch an exception and then we will re-throw it. Here is the client code to call the API.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="APICall.aspx.cs" Inherits="WebApplication1.APICall" %>
<head runat="server">
<script src="jquery-1.7.1.js" type="text/javascript"></script>
<script>
$(document).ready(function () {
$("#Save").click(function () {
$.ajax({
url: 'http://localhost:3413/api/person',
type: 'POST',
dataType: 'json',
success: function (data, textStatus, xhr) {
console.log(xhr);
},
error: function (xhr, textStatus, errorThrown) {
console.log(textStatus);
}
});
});
});
</script>
</head>
<body>
<input type="button" id="Save" value="Save Data" />
</body>
</html>
Here is the implementation of the Web API.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace WebApplication1.WebAPI
{
public class personController : ApiController
{
[HttpPost]
public void PostAction()
{
try
{
int zero = 0;
int a = 100 / zero;
}
catch (Exception ex)
{
throw new Exception("Not possible to devide by 0");
}
}
}
}
Please observe that we are generating a "DevideByZero" Exception intentionally and the program is throwing the following exception. Now, observe that the Exception was unhandled by the user, that's fine.
In the error message from the ajax() function we are getting a generalized message "Internal Server Error" rather than "DevideByZeroException" or our custom message returned by a new exception object.
So, we are not getting a prompt with an actual exception. Ok, then this is not the correct way to handle exceptions in the Web API.
Handle exception in proper way
The title is not relevant, rather than the proper way I should write some technical description of that. Anyway we will see the actual way to handle an exception in the Web API. Here is the client code.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="APICall.aspx.cs" Inherits="WebApplication1.APICall" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<script src="jquery-1.7.1.js" type="text/javascript"></script>
<script>
$(document).ready(function () {
$("#Save").click(function () {
$.ajax({
url: 'http://localhost:3413/api/person',
type: 'POST',
dataType: 'json',
success: function (data, textStatus, xhr) {
console.log(xhr);
},
error: function (xhr, textStatus, errorThrown) {
console.log(textStatus);
}
});
});
});
</script>
</head>
<body>
<input type="button" id="Save" value="Save Data" />
</body>
</html>
Here is our server-side code implementation.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace WebApplication1.WebAPI
{
public class personController : ApiController
{
[HttpPost]
public void PostAction()
{
try
{
int zero = 0;
int a = 100 / zero;
}
catch
{
var resp = new HttpResponseMessage(HttpStatusCode.ExpectationFailed)
{
ReasonPhrase = "Devide by 0 Exception"
};
throw new HttpResponseException(resp);
}
}
}
}
We are seeing that, rather than throwing a new exception, we are throwing an object of the HttpResponseException class and passing one object of the HttpResponseMessage object through it and this message contains information about the actual exception. Now we are getting actual error message in client end.
Another example from a real scenario
In the example above we saw how to configure a HttpResponseMessage object to throw a HttpResponseException in the Web API. That's cool. In this example we will see one more scenario. We know that the Web API is one kind of service and very obviously it will work with the user's input . Like a user may want to search something in the DB using the Web API. Now, there is no guarantee that the information will be present in the DB. If not present than we can throw an object not found exception.
Here is implementation of client code.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="APICall.aspx.cs" Inherits="WebApplication1.APICall" %>
<head runat="server">
<script src="jquery-1.7.1.js" type="text/javascript"></script>
<script>
$(document).ready(function () {
$("#Save").click(function () {
$.ajax({
url: 'http://localhost:3413/api/person?Id=3',
type: 'POST',
dataType: 'json',
success: function (data, textStatus, xhr) {
console.log(xhr);
},
error: function (xhr, textStatus, errorThrown) {
console.log(errorThrown);
}
});
});
});
</script>
</head>
<body>
<input type="button" id="Save" value="Save Data" />
</body>
</html>
Now, within the Web API we are returning a specific person, depending on the input parameter passed by URL. If the person is not present in the List then it will throw a NotFound exception.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace WebApplication1.WebAPI
{
public class person
{
public string name { get; set; }
public string surname { get; set; }
}
public class personController : ApiController
{
[HttpPost]
public person PostAction([FromUri] string Id)
{
person[] p = new person[2];
p[0] = new person();
p[0].name = "sourav";
p[0].surname = "Kayal";
p[1] = new person();
p[1].name = "Ajay";
p[1].surname = "Joshi";
try
{
return p[Convert.ToInt32(Id)];
}
catch
{
var resp = new HttpResponseMessage(HttpStatusCode.NotFound)
{
StatusCode = HttpStatusCode.NotFound,
ReasonPhrase = "Person Not Found"
};
throw new HttpResponseException(resp);
}
}
}
}
Here is the output of the example above.
Conclusion
In this article we have learned the exception handling mechanism in the Web API. This is very crucial in project development and hope you have found at least some use of the resources here. Happy coding.