2012-04-23 10 views
9

Ich habe einen Filter erstellt, der das System.Web.Http.Filters.ActionFilterAttribute in der ASP.net Web API erbt und möchte auf einige der Daten innerhalb des HttpActionExecutedContext Ergebnisobjekts zugreifen.Getting the HttpActionExecutedContext Ergebniswerte

In welchem ​​Stadium/wann wird dieses Objekt aufgefüllt? Wie habe ich es beim Überschreiben der OnActionExecuted-Methode betrachtet und es ist immer Null?

Irgendwelche Ideen?

Edit:

zum Beispiel hier in meinem benutzerdefinierten Filter:

public override OnActionExecuted(HttpActionExecutedContext context) 
{ 
    //context.Result.Content is always null 

    base.OnActionExecuted(context); 
} 
+0

einige Teile Code. Verwenden Sie eine Beta-Version oder eine Quellcode-Version? Für mich geht das. – Aliostad

+0

@Aliostad Hallo ich benutze die Beta-Version. Was benutzt du? – gdp

+0

Ich benutze die gleiche, Beta-Version. – Aliostad

Antwort

7

Ended mit ReadAsStringAsync auf dem Inhalt Ergebnis auf. Ich habe versucht, auf die Eigenschaft zuzugreifen, bevor die eigentliche Anfrage beendet wurde.

+0

ReadAsStringAsync könnte "" zurückgeben, wenn der Content-Stream bereits gelesen wurde (sehr, sehr wahrscheinlich). Verwenden Sie die @ virender-Lösung, um sicherzustellen, dass Sie den Stream immer von Position 0 aus lesen. – mikesigs

2

Während die preisgekrönte Antwort auf ReadAsStringAsync bezog, hatte die Antwort kein Beispiel. Ich folgte dem Rat von gdp und leitete ein etwas funktionierendes Beispiel ...

Ich schuf eine einzelne Klasse namens MessageInterceptor. Ich habe nicht mehr getan, als von ActionFilterAttribute abzuleiten, und es fing sofort an, webAPI-Methodenaufrufe abzufangen, bevor der Controller es erhielt und nachdem der Controller fertig war. Hier ist meine letzte Klasse. In diesem Beispiel wird der XML-Serializer verwendet, um die Anforderung und die Antwort in einer XML-Zeichenfolge abzurufen. In diesem Beispiel werden die Anforderung und die Antwort als befüllte Objekte gefunden. Dies bedeutet, dass die Deserialisierung bereits erfolgt ist. Das Sammeln der Daten aus einem aufgefüllten Modell und das Serialisieren in eine XML-Zeichenfolge ist eine Darstellung der Anfrage und Antwort - nicht der tatsächlichen Postanforderung und Antwort, die von IIS zurückgeschickt wird.

Codebeispiel - MessageInterceptor

using System.IO; 
using System.Linq; 
using System.Web.Http.Controllers; 
using System.Web.Http.Filters; 
using System.Xml.Serialization; 

namespace webapi_test 
{ 
    public class MessageInterceptor : ActionFilterAttribute 
    { 
     public override void OnActionExecuting(HttpActionContext actionContext) 
     { 
      base.OnActionExecuting(actionContext); 
      var headers = actionContext.Request.Content.Headers.ToString(); 
      var request = actionContext.ActionArguments.FirstOrDefault().Value; 
      var xml = SerializeXMLSerializer(request, ""); 
     } 

     public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 
     { 
      base.OnActionExecuted(actionExecutedContext); 
      var headers = actionExecutedContext.Response.Content.Headers.ToString(); 
      var response = actionExecutedContext.Response.Content.ReadAsStringAsync().Result; 
      var xml = SerializeXMLSerializer(response, ""); 
     } 

     public static string SerializeXMLSerializer(object o, string nameSpace) 
     { 
      string serializedValue; 
      var writer = new StringWriter(); 
      XmlSerializer serializer = new XmlSerializer(o.GetType(), nameSpace); 
      serializer.Serialize(writer, o); 
      serializedValue = writer.ToString(); 
      return serializedValue; 
     } 
    } 
} 
+0

Sie sollten nicht direkt auf .Result zugreifen, blockiert, Sie möchten auch Async/Warten auf ReadAsStringAsync. – gdp

+1

gdp - nicht sicher, ich verstehe Ihre Kommentare "möchte Asnyc/warten auf die ReadAsStringAsync". Der OnActionExecuted tritt auf, nachdem der Controller ausgelöst und beendet wurde. Es gibt nichts zu blockieren oder zu warten - die gesamte Antwort ist verfügbar ... – barrypicker

4

Mit dieser Funktion können Körper der Anfrage in web api

private string GetBodyFromRequest(HttpActionExecutedContext context) 
{ 
    string data; 
    using (var stream = context.Request.Content.ReadAsStreamAsync().Result) 
    { 
     if (stream.CanSeek) 
     { 
      stream.Position = 0; 
     } 
     data = context.Request.Content.ReadAsStringAsync().Result; 
    } 
    return data; 
} 
+0

Es funktioniert für 'HttpActionExecutedContext', aber was ist mit' System.Web.Mvc.ActionExecutedContext'? –

0

Verwenden unten bekommen Antwortstring zu lesen:

public static string GetResponseContent(HttpResponseMessage Response) 
    { 
     string rawResponse = string.Empty; 
     try 
     { 
      using (var stream = new StreamReader(Response.Content.ReadAsStreamAsync().Result)) 
      { 
       stream.BaseStream.Position = 0; 
       rawResponse = stream.ReadToEnd(); 
      } 
     } 
     catch (Exception ex) { throw; } 
     return rawResponse; 
    }