Ich habe eine ziemlich einfache Web-API-Anwendung, die derzeit eine Route eingerichtet hat. Wenn der Benutzer versucht, auf eine andere Route zuzugreifen, erhält er 404 zurück, aber der Hauptteil des 404 ist HTML anstelle von JSON (was der Header für die Annahme verlangt). Was ist einfachste (am wenigsten Code/config zu meinem Projekt hinzugefügt) Weg, um IIS auf Anfragen von nicht existierenden Routen mit einer JSON-Fehlerantwort statt einer Webseite zu reagieren?Wie gebe ich Json für 404s und 403s in WebAPI zurück?
Die gleiche Frage gilt für 403s. Wenn ich versuche, zur Wurzel meiner Anwendung zu navigieren, bekomme ich eine 403 zurück, wiederum als Webseite. Ich würde es vorziehen, ein 404 sein, aber die größere Frage ist, wie mache ich alle Antworten aus meiner Anwendung JSON statt nur Antworten auf gültige Routen? Ich erwähne die 403, weil ich nach einer breiteren Lösung suche, als nur eine Catch-All-Route einzurichten, da ich nicht glaube, dass mir das bei der 403 oder einer anderen zufälligen Ausnahme hilft, die außerhalb einer Controller-Aktion auftritt.
Am liebsten möchte ich, dass meine Anwendung den Header akzeptiert. Da meine API derzeit jedoch nur JSON unterstützt, bin ich bereit, mit (vorläufig) immer mit JSON zu reagieren.
Ich verwende WebAPI 2.2 und .NET 4.5.2.
bearbeiten
Dies ist kein Formatierer Problem. Die Formatierer werden korrekt auf erfolgreiche Nachrichten angewendet, wobei der akzeptierende Header in der Anforderung berücksichtigt wird. Dies ist insbesondere ein Problem mit unbehandelten Routen und Webserverfehlern (wie beim Zugriff auf den Webstamm verboten).
bearbeiten 2
Schritte zum Reproduzieren:
- Öffnen Sie Visual Studio 2013 Update 4
- Neues Projekt
- Wählen Sie .NET Framework 4.5.2
- Vorlagen wählen > Visual C#> Web> ASP.NET-Webanwendung
- Wählen Sie "Leer", lassen Sie alle Ordner und Kernreferenzen unmarkiert.
- Klicken Sie mit der rechten Maustaste auf das Projekt> Hinzufügen> Neues Gerüstelement> Web API 2 Controller - Leer
- Ändern Sie DefaultController wie unten gezeigt.
- Ändern Sie WebApiConfig.cs wie unten gezeigt.
- Run/Debug
Was ich erwarte, ist, dass, wenn ich zu http://localhost:<port>/api/do_stuff
navigieren Ich sehe Success!
in XML- oder JSON je nach akzeptieren Header (was ich tun), und wenn ich zu einer anderen Seite navigieren soll ich sehen Failure!
(was ich nicht). Wenn ich stattdessen zu einer anderen Seite navigiere, sehe ich die 404-Antwort von IIS.
DefaultController.cs:
[RoutePrefix("api")]
public class DefaultController : ApiController
{
[HttpGet]
[Route("do_stuff")]
public String DoStuff()
{
return "Success!";
}
}
WebApiConfig.cs:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Filters.Add(new CustomExceptionFilter());
}
private class CustomExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext.Response.StatusCode == System.Net.HttpStatusCode.NotFound)
{
actionExecutedContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.NotFound)
{
Content = new StringContent(@"""Failure!"""),
};
}
}
}
}
bearbeitet 3
ich auch einen globalen Exception-Handler und Ausnahme Hinzufügen Logger versucht habe, wie hier gezeigt: http://www.asp.net/web-api/overview/error-handling/web-api-global-error-handling
Weder aufgerufen werden, wenn ich versuche, auf einen ungültiges zu navigieren Im obigen Beispiel route oder zum Site-Root navigieren.
Wenn der Accept-Header ist text/html und nicht application/json dann Rückkehr HTML könnte die richtige Sache irgendwie zu tun. –
Ich glaube nicht, dass diese Antwort hier gilt, weil der Kopf für die Annahme derzeit auf application/json gesetzt ist und ich Text/HTML zurückbekomme. Dies bedeutet, dass meine Formatierer für fehlende Routen und verbotene Anfragen nicht respektiert werden. –
Obwohl ich die von Ihnen erwähnten Schritte überprüfen und zurücksetzen, aber Sie können CustomExceptionFilter eine eigenständige öffentliche Klasse machen, was ist der Punkt, um es zu einer privaten Klasse zu machen, mein Verständnis ist, auch wenn Sie registriert haben, wird es nur für Ausnahmen arbeiten WebAPIConfig und deshalb löst es keine der aufgetretenen Exceptions aus. –