Ich gebe ein NotFound zurück IHttpActionResult
, wenn in meiner WebApi GET-Aktion etwas nicht gefunden wurde. Zusammen mit dieser Antwort möchte ich eine benutzerdefinierte Nachricht und / oder die Ausnahmemeldung (falls vorhanden) senden. Die aktuellen ApiController
‚s NotFound()
Verfahren liefern nicht eine Überlast eine Nachricht zu übergeben.
Gibt es eine Möglichkeit, dies zu tun? oder muss ich meinen eigenen Brauch schreiben IHttpActionResult
?
c#
asp.net-web-api
http-status-code-404
httpresponse
Ajay Jadhav
quelle
quelle
Antworten:
Sie müssen Ihr eigenes Aktionsergebnis schreiben, wenn Sie die Form der Antwortnachricht anpassen möchten.
Wir wollten die gängigsten Formen von Antwortnachrichten für Dinge wie einfache leere 404s bereitstellen, aber wir wollten diese Ergebnisse auch so einfach wie möglich halten. Einer der Hauptvorteile der Verwendung von Aktionsergebnissen besteht darin, dass Ihre Aktionsmethode für Unit-Tests viel einfacher ist. Je mehr Eigenschaften wir den Aktionsergebnissen hinzufügen, desto mehr Dinge muss Ihr Komponententest berücksichtigen, um sicherzustellen, dass die Aktionsmethode das tut, was Sie erwarten.
Ich möchte oft auch die Möglichkeit haben, eine benutzerdefinierte Nachricht bereitzustellen. Sie können also einen Fehler protokollieren, damit wir in Betracht ziehen, dieses Aktionsergebnis in einer zukünftigen Version zu unterstützen: https://aspnetwebstack.codeplex.com/workitem/list/advanced
Eine schöne Sache an den Aktionsergebnissen ist jedoch, dass Sie immer ziemlich einfach Ihre eigenen schreiben können, wenn Sie etwas anderes machen möchten. So könnten Sie es in Ihrem Fall tun (vorausgesetzt, Sie möchten die Fehlermeldung in Text / Klartext; wenn Sie JSON möchten, würden Sie etwas anderes mit dem Inhalt tun):
Dann können Sie in Ihrer Aktionsmethode einfach Folgendes tun:
Wenn Sie eine benutzerdefinierte Controller-Basisklasse verwendet haben (anstatt direkt von ApiController zu erben), können Sie auch das "this" entfernen. Teil (der leider beim Aufrufen einer Erweiterungsmethode erforderlich ist):
quelle
Hier ist ein Einzeiler für die Rückgabe eines IHttpActionResult NotFound mit einer einfachen Nachricht:
quelle
Sie können verwenden,
ResponseMessageResult
wenn Sie möchten:Ja, wenn Sie viel kürzere Versionen benötigen, müssen Sie wahrscheinlich Ihr benutzerdefiniertes Aktionsergebnis implementieren.
quelle
Sie können die ReasonPhrase-Eigenschaft der HttpResponseMessage-Klasse verwenden
quelle
Sie können ein benutzerdefiniertes Ergebnis für ausgehandelte Inhalte erstellen, wie von d3m3t3er vorgeschlagen. Allerdings würde ich von erben. Wenn Sie es nur für die Rückgabe von NotFound benötigen, müssen Sie den http-Status vom Konstruktor nicht initialisieren.
quelle
Ich habe es gelöst, indem ich einfach
OkNegotiatedContentResult
den HTTP-Code in der resultierenden Antwortnachricht abgeleitet und überschrieben habe. Mit dieser Klasse können Sie den Inhaltskörper mit einem beliebigen HTTP-Antwortcode zurückgeben.quelle
Wenn Sie
NegotitatedContentResult<T>
wie erwähnt von der Basis erben und Ihre nicht transformieren müssencontent
(z. B. nur eine Zeichenfolge zurückgeben möchten), müssen Sie dieExecuteAsync
Methode nicht überschreiben .Sie müssen lediglich eine geeignete Typdefinition und einen Konstruktor bereitstellen, der der Basis mitteilt, welcher HTTP-Statuscode zurückgegeben werden soll. Alles andere funktioniert einfach.
Hier sind Beispiele für beide
NotFound
undInternalServerError
:Und dann können Sie entsprechende Erweiterungsmethoden erstellen für
ApiController
(oder in einer Basisklasse, falls vorhanden):Und dann funktionieren sie genauso wie die eingebauten Methoden. Sie können entweder die vorhandene
NotFound()
oder Ihre neue benutzerdefinierte Person aufrufenNotFound(myErrorMessage)
.Und natürlich können Sie die "hartcodierten" Zeichenfolgentypen in den benutzerdefinierten Typdefinitionen entfernen und sie generisch belassen, wenn Sie möchten, aber dann müssen Sie sich möglicherweise um die
ExecuteAsync
Dinge kümmern , je nachdem, was Sie<T>
tatsächlich sind.Sie können den Quellcode durchsuchen, um
NegotiatedContentResult<T>
zu sehen, was er tut. Da ist nicht viel dran.quelle
Ich musste eine
IHttpActionResult
Instanz im Hauptteil einerIExceptionHandler
Klasse erstellen , um dieExceptionHandlerContext.Result
Eigenschaft festzulegen. Ich wollte aber auch einen Brauch setzenReasonPhrase
.Ich fand, dass a ein
ResponseMessageResult
WrapHttpResponseMessage
einschließen könnte (wodurch ReasonPhrase einfach eingestellt werden kann).Beispielsweise:
quelle
Ich weiß, dass PO mit einem Nachrichtentext gefragt wurde, aber eine andere Option, um nur einen 404 zurückzugeben, besteht darin, dass die Methode ein IHttpActionResult zurückgibt und die StatusCode-Funktion verwendet
quelle
Bei den Antworten fehlt ein kleines Problem mit der Entwicklergeschichte. Die
ApiController
Klasse macht immer noch aNotFound()
Methode zur Verfügung, die Entwickler verwenden können. Dies würde dazu führen, dass eine 404-Antwort einen unkontrollierten Ergebniskörper enthält.Ich präsentiere hier einige Teile des Codes " bessere ApiController NotFound-Methode ", die eine weniger fehleranfällige Methode bietet, bei der Entwickler nicht wissen müssen, "wie man eine 404 besser sendet".
ApiController
aufgerufen erbtApiController
NotFound
Methode , damit Entwickler die erste verfügbare API verwenden können[Obsolete("Use overload instead")]
protected NotFoundResult NotFound(string message)
, das Sie fördern möchtenNegotiatedContentResult
. siehe beigefügte bessere NotFoundResult-Klasse .quelle