Gibt es eine Möglichkeit, um get-request-body in .NET Core FilterAttribute?
Beispiel meiner Anfrage
http://localhost:8065/api/note
POST
content-type:application/json
request body: { "id" : "1234", "title" : "test", "status" : "draft"}
und die Antwort sollte
{ "msg" : "ok", "code" : 1}
Die Aktion
public async Task<IActionResult> Post([FromBody]NoteModel model)
Haben, um jede Anfrage protokolliert automatisch erstelle ich ein Attribut um diesen job zu machen. Das Attribut sieht wie folgt aus: (aus Microsoft Docs)
public class SampleActionFilterAttribute : TypeFilterAttribute
{
public SampleActionFilterAttribute():base(typeof(SampleActionFilterImpl))
{
}
private class SampleActionFilterImpl : IActionFilter
{
private readonly ILogger _logger;
public SampleActionFilterImpl(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<SampleActionFilterAttribute>();
}
public void OnActionExecuting(ActionExecutingContext context)
{
}
public void OnActionExecuted(ActionExecutedContext context)
{
_logger.LogDebug("[path]" + context.HttpContext.Request.Path);
_logger.LogDebug("[method]" + context.HttpContext.Request.Method);
_logger.LogDebug("[body]"); //log request body, expectation: { "id" : "1234", "title" : "test", "status" : "draft"}
_logger.LogDebug("[statuscode]" + context.HttpContext.Response.StatusCode);
_logger.LogDebug("[response]"); //log response
}
}
}
Ich versuche es mal mit streamReader zu erhalten Wunsch Körper bekommen nur leere Zeichenfolge.
StreamReader reader = new StreamReader(context.HttpContext.Request.Body);
string text = reader.ReadToEnd();
Ist, dass, weil der Körper zum Lesen [fromBody] vom controller, so dass der stream kann nicht gelesen werden zweimal? Wenn ja, wie soll ich denn get-request-body und eine Antwort auf die OnActionExecuted
Methode?
Update:
Habe ich nur kopiert, Legen Sie den code in meinem Projekt nicht funktioniert. Hier ist die debug-gif
- Also, es wurde gut beantwortet, bei stackoverflow.com/a/43404745/4074527.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Entsprechend " Beste Weg, um log/read-request-body in eine middleware " - thread, sollten die folgenden arbeiten:
Auch ähnlicher Ansatz beschrieben, in Read-request-body zweimal SO ein post
Update: obigen Ansatz in
ReadBodyAsString
mit arbeiten, wenn verwendet, in der middleware, die nicht in Aktion filter. Der Unterschied ist, dass beim action filter aufrufen (auch fürOnActionExecuting
), die der Körper stream bereits gelesen wurde und[FromBody] model
aufgefüllt wurde.Den guten nesw ist das so es ist möglich, zu erhalten Modell auch direkt in Aktion filter mit
context.ActionArguments["<model_name>"]
. In deinem Fall:ReadBodyAsString
Methode inOnActionExecuting
noch Holen wollen, finden Sie in der gif, die ich eingefügt. (Die[fromBody] model
Wert hat).context.ActionArguments
direkt zu bekommen, Modells in action filter, oder wenn Sie wollen, um die Arbeit mit raw-request-body, zu bewegen, um middleware-Ansatz für die Protokollierung.context.ActionArguments
mein problem gelöst. Ich habe gerade Schleife jedes Element in ActionArgumetns und verwenden newtonsoft.json serialisiert als string und log.Wenn Sie IActionResult im Controller und Sie möchten das .NET-Objekte, Sie können schreiben, ein filter wie dieser:
Durch den Punkt, es trifft OnActionExecuted, die ObjectResult Aufgabe bereits abgeschlossen hat, so können Sie einfach extrahieren Sie den Wert. Sie können auch den StatusCode mit objResult.StatusCode.
In die controller, return Ok(...) tatsächlich schafft eine OkObjectResult, etc.
Wenn Sie speziell möchten den serialzied Ergebnis, Legen Sie dann die Antwort ist mehr gültig.