-
Notifications
You must be signed in to change notification settings - Fork 2
Errorhandling
There are a few ways to handle errors in your services, so which one you choose depends on your situation and preference.
If you throw an exception in your controller code, out of the box NServiceMVC will return an error response.
If you throw an exception that implements NServiceMVC.IServiceException (such as NServiceMVC.ServiceException), NServiceMVC will return a specific HTTP response code (part of IServiceException), and also serialize a model object like it normally would. This method is the most RESTful as it allows control of an exact HTTP response code, and it also allows returning more detailed data using an alternate model object than normally is returned by the service.
// Example error using default 500 response code
Throw New NServiceMVC.ServiceException(new MyValidationFailedDetail {
Message = "Username contains invalid characters.", Field = "Username"
});
// Example error using specific 401 unauthorized code
Throw New NServiceMVC.ServiceException(
System.Net.HttpStatusCode.Unauthorized,
new MyErrorDetail { Detail = "You are not allowed here." }
);
You can freely extend NServiceMVC.ServiceException and/or implement NServiceMVC.IServiceException in your own exception classes.
Internally, NServiceMVC uses NServiceMVC.WebStack.HttpStatusContentResult when returning status codes. This is useful in, for example, a controller/filter during OnActionExecuting() method to return a response.
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!IsAuthorized())
{
filterContext.Result = new NServiceMVC.WebStack.HttpStatusContentResult(
(int)System.Net.HttpStatusCode.Unauthorized) {
Content = "No active session. Please login first."
}
);
}
}
There are several ways to respond outside of the context of NServiceMVC.
One way is you can implement your own response types using your own wrapper class. This is not very RESTful since it returns a 200 OK response even if there is an error, but in some cases may be easier to deal with on the client-side.
// response wrapper
public class Response<T>
{
public Boolean Success { get; set; }
public T Obj { get; set; }
}
// Controller method
[GET("test")]
public Response<MyResult> Test()
{
MyResult result = LoadMyResult(); // call into your service layer or whatever
if (result != null)
return new Response<MyResult>() { Obj = result, Success = true };
else
return new Response<MyResult>() { Success = false };
}