Web api is designed to return Http Status codes when there is a failure. You can then include the message in the response. Also here is a list of possible status codes that you could send back. There are built in methods for the more common response reasons. So your Web Api method ends up looking something like this (see code sample below). Now the calling client will know if a status of 200 is received (default for Ok) then everything was processed correctly on the server, otherwise handle the Http status code and do something with the message or response object.
This pattern will prevent you from having to add a success
and message
property to all of your responses. It also allows you to catch some common validation using Action Filters like authorization checks using the Authorize
filter attribute.
[HttpGet]
public IHttpActionResult GetData()
{
try {
object somethingToReturn;
// do something to populate your result
return Ok(somethingToReturn);
}
catch(SomeDataException someException){
// log or do something
return BadRequest("The object A could not be found with these parameters!");
}
catch(Exception totallyUnexpectedException){
// log or do something
return InternalServerError();
}
}
So, why not use mvc controller instead web api?
This question has been asked before, see these SO posts
Edit
Based on the latest comment. Here is some code that you can use to dynamically create a generic response object without having to manually wrap everything. By creating some extension methods you can abstract the response wrapper to some helper methods.
public class TestController : ApiController
{
[HttpGet]
public IHttpActionResult Get()
{
var success = false;
try
{
var someResult = new SomeObject() {Name = "igor"};
// do something
if (success)
return this.Ok(new SomeObject() {Name = "igor"}); // sends success
return this.Failure(someResult, "some known error"); // sends failure with partial object (if possible)
}
catch (Exception ex)
{
return this.Failure("Something bad happened"); // sends failure with no object because you could not create it
}
}
}
public static class ApiControllerExtensions
{
public static OkNegotiatedContentResult<ResultWrapper<T>> Ok<T>(this ApiController controller, T content)
{
return new OkNegotiatedContentResult<ResultWrapper<T>>(new ResultWrapper<T>() { Result = content, Success = true, Message = null }, controller);
}
public static OkNegotiatedContentResult<ResultWrapper<T>> Failure<T>(this ApiController controller, T content, string message)
{
return new OkNegotiatedContentResult<ResultWrapper<T>>(new ResultWrapper<T>() { Result = content, Success = false, Message = message }, controller);
}
public static OkNegotiatedContentResult<FailureResult> Failure(this ApiController controller, string message)
{
return new OkNegotiatedContentResult<FailureResult>(new FailureResult() { Success = false, Message = message }, controller);
}
}
public class ResultWrapper<T>
{
public T Result { get; set; }
public string Message { get; set; }
public bool Success { get; set; }
}
public class FailureResult // simple class used strictly for failures (unless you ever have an operation with no result that can succeed then modify the name and reuse)
{
public string Message { get; set; }
public bool Success { get; set; }
}
public class SomeObject
{
public string Name { get; set; }
}
Edit
Not sure if you have already tried this but I checked out the documentation for extjs.
Callback Options
Not every AJAX request succeeds: sometimes the server is down, or your internet connection drops, or something else bad happens. Ext.Ajax allows you to specify separate callbacks for each of these cases
Ext.Ajax.request({
url: 'myUrl',
success: function(response) {
console.log("Spiffing, everything worked");
},
failure: function(response) {
console.log("Curses, something terrible happened");
},
callback: function(options, success, response) {
console.log("It is what it is");
}
});
So based on this pattern it seems like my first scenario, using Web API as Microsoft intended with proper failure status codes in case of error, should be possible.