Domanda

Problem:

I need to handle web api 2 exceptions and return a rich object with the correct status code (401 for Unauthorized, 404 for ContentNotFound, etc) and some extra information as the content. Moreover, I need the content to look like a serialized Exception object (have the message, exceptionMessage, stackTrace, ... properties).

Suggested Solutions:

  1. Create custom exception classes and writing a custom exception filter to apply to any controller's action. this custom exception filters handles the exception thrown according to it's type (one of the custom exceptions that I've already defined) and responds accordingly via something like this (filter's code):

    context.Response = context.Request.CreateErrorResponse(HttpStatusCode.Unauthorized,
                                        new Exception("my exception")));
    
  2. wrapping the already written web api 2 *ActionResult classes ( System.Web.Http.Results.UnauthorizedResult Unauthorized(), System.Web.Http.Results.OkResult Ok(), etc ) and adding some custom data to them and use them so that their result get passed to client every time they're called (the problem is in this case my controller's action's return type should be IHttpActionResult which is not as easily testable and readable as a strongly typed action).

What solution should I choose? Or is there any other way to do what I'm trying to achieve here?

È stato utile?

Soluzione

Or you could use the built-in, out-of-the-box solution: exception filters.

Furthermore, you may be interested on exception handling starting from Web API 2.x.

Altri suggerimenti

From what I understand you don't want to handle exceptions thrown by the code, rather create them in your action methods. For the case where exceptions are thrown by other areas in the code (other things you call inside your actions or by other filters, you can either use exception filters or global error handling).

Hence I would go with your second approach (though you don't need to customize the action results much). Your code is actually a lot more easy to unit test with IHttpActionResult, because you can inspect the result type directly. In fact one of the reasons IHttpActionResults where added is to simplify unit testing.

The flow of your code is simpler as you don't need to throw to generate errors, and you can always inspect the content of an ok(returnValue) as you can see below.

[TestMethod]
public void GetProduct_ShouldReturnCorrectProduct()
{
    var testProducts = GetTestProducts();
    var controller = new SimpleProductController(testProducts);

    var result = controller.GetProduct(4) as OkNegotiatedContentResult<Product>;
    Assert.IsNotNull(result);
    Assert.AreEqual(testProducts[3].Name, result.Content.Name);
}

http://www.asp.net/web-api/overview/testing-and-debugging/unit-testing-with-aspnet-web-api

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top