Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I den här artikeln beskrivs fel- och undantagshantering i ASP.NET webb-API.
HttpResponseException
Vad händer om en Web API-kontrollant genererar ett ohanterat undantag? Som standard översätts de flesta undantag till ett HTTP-svar med statuskod 500, internt serverfel.
Typen HttpResponseException är ett specialfall. Det här undantaget returnerar all HTTP-statuskod som du anger i undantagskonstruktorn. Följande metod returnerar till exempel 404, Hittades inte, om id-parametern inte är giltig.
public Product GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
}
Om du vill ha mer kontroll över svaret kan du även skapa hela svarsmeddelandet och inkludera det med HttpResponseException:
public Product GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
var resp = new HttpResponseMessage(HttpStatusCode.NotFound)
{
Content = new StringContent(string.Format("No product with ID = {0}", id)),
ReasonPhrase = "Product ID Not Found"
};
throw new HttpResponseException(resp);
}
return item;
}
Undantagsfilter
Du kan anpassa hur webb-API hanterar undantag genom att skriva ett undantagsfilter. Ett undantagsfilter körs när en kontrollantmetod genererar ett ohanterat undantag som inte är ett HttpResponseException-undantag . HttpResponseException-typen är ett specialfall eftersom den är särskilt utformad för att returnera ett HTTP-svar.
Undantagsfilter implementerar gränssnittet System.Web.Http.Filters.IExceptionFilter . Det enklaste sättet att skriva ett undantagsfilter är att härleda från klassen System.Web.Http.Filters.ExceptionFilterAttribute och åsidosätta metoden OnException .
Anmärkning
Undantagsfilter i ASP.NET webb-API liknar dem i ASP.NET MVC. De deklareras dock i ett separat namnområde och fungerar separat. I synnerhet hanterar klassen HandleErrorAttribute som används i MVC inte undantag som genereras av webb-API-kontrollanter.
Här är ett filter som konverterar NotImplementedException-undantag till HTTP-statuskod 501, Inte implementerad:
namespace ProductStore.Filters
{
using System;
using System.Net;
using System.Net.Http;
using System.Web.Http.Filters;
public class NotImplExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
if (context.Exception is NotImplementedException)
{
context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
}
}
}
}
Egenskapen Svar för objektet HttpActionExecutedContext innehåller HTTP-svarsmeddelandet som ska skickas till klienten.
Registrera undantagsfilter
Det finns flera sätt att registrera ett undantagsfilter för webb-API:
- Efter åtgärd
- Efter styrenhet
- Globalt
Om du vill tillämpa filtret på en specifik åtgärd lägger du till filtret som ett attribut i åtgärden:
public class ProductsController : ApiController
{
[NotImplExceptionFilter]
public Contact GetContact(int id)
{
throw new NotImplementedException("This method is not implemented");
}
}
Om du vill tillämpa filtret på alla åtgärder på en kontrollant lägger du till filtret som ett attribut i kontrollantklassen:
[NotImplExceptionFilter]
public class ProductsController : ApiController
{
// ...
}
Om du vill tillämpa filtret globalt på alla webb-API-kontrollanter lägger du till en instans av filtret i samlingen GlobalConfiguration.Configuration.Filters . Undantagsfilter i den här samlingen gäller för alla åtgärder för webb-API-kontrollanter.
GlobalConfiguration.Configuration.Filters.Add(
new ProductStore.NotImplExceptionFilterAttribute());
Om du använder projektmallen "ASP.NET MVC 4 Web Application" för att skapa projektet placerar du konfigurationskoden för webb-API:et WebApiConfig i klassen, som finns i mappen App_Start:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new ProductStore.NotImplExceptionFilterAttribute());
// Other configuration code...
}
}
HttpError
HttpError-objektet ger ett konsekvent sätt att returnera felinformation i svarstexten. I följande exempel visas hur du returnerar HTTP-statuskod 404 (hittades inte) med en HttpError i svarstexten.
public HttpResponseMessage GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
var message = string.Format("Product with id = {0} not found", id);
return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
}
else
{
return Request.CreateResponse(HttpStatusCode.OK, item);
}
}
CreateErrorResponse är en tilläggsmetod som definierats i klassen System.Net.Http.HttpRequestMessageExtensions . Internt skapar CreateErrorResponse en HttpError-instans och skapar sedan en HttpResponseMessage som innehåller HttpError.
Om metoden lyckas i det här exemplet returneras produkten i HTTP-svaret. Men om den begärda produkten inte hittas innehåller HTTP-svaret en HttpError i begärandetexten. Svaret kan se ut så här:
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Date: Thu, 09 Aug 2012 23:27:18 GMT
Content-Length: 51
{
"Message": "Product with id = 12 not found"
}
Observera att HttpError serialiserades till JSON i det här exemplet. En fördel med att använda HttpError är att det går igenom samma process för innehållsförhandling och serialisering som alla andra starkt skrivna modeller.
HttpError- och modellverifiering
För modellverifiering kan du skicka modelltillståndet till CreateErrorResponse för att inkludera valideringsfelen i svaret:
public HttpResponseMessage PostProduct(Product item)
{
if (!ModelState.IsValid)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
// Implementation not shown...
}
Det här exemplet kan returnera följande svar:
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Content-Length: 320
{
"Message": "The request is invalid.",
"ModelState": {
"item": [
"Required property 'Name' not found in JSON. Path '', line 1, position 14."
],
"item.Name": [
"The Name field is required."
],
"item.Price": [
"The field Price must be between 0 and 999."
]
}
}
Mer information om modellverifiering finns i Modellverifiering i ASP.NET webb-API.
Använda HttpError med HttpResponseException
Föregående exempel returnerar ett HttpResponseMessage-meddelande från kontrollantåtgärden, men du kan också använda HttpResponseException för att returnera en HttpError. På så sätt kan du returnera en starkt skriven modell i det normala framgångsfallet, samtidigt som du returnerar HttpError om det finns ett fel:
public Product GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
var message = string.Format("Product with id = {0} not found", id);
throw new HttpResponseException(
Request.CreateErrorResponse(HttpStatusCode.NotFound, message));
}
else
{
return item;
}
}