2012-04-23 23 views
9

He creado un filtro que hereda System.Web.Http.Filters.ActionFilterAttribute en asp.net web api y desea acceder a algunos de los datos dentro del objeto de resultado HttpActionExecutedContext.Obteniendo HttpActionExecutedContext Valores de resultado

¿En qué etapa/cuándo se llena este objeto? Como lo miré al anular el método OnActionExecuted y siempre es nulo?

¿Alguna idea?

Editar:

por ejemplo aquí en mi filtro personalizado:

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

    base.OnActionExecuted(context); 
} 
+0

Compartir algunos código. ¿Estás utilizando versión beta o versión de código fuente? Esto funciona para mi. – Aliostad

+0

@Aliostad Hola, estoy usando la versión beta. ¿Que estas usando? – gdp

+0

Estoy usando la misma versión beta. – Aliostad

Respuesta

7

Acabamos yendo en ReadAsStringAsync en el resultado contenido. Estaba intentando acceder a la propiedad antes de que la solicitud real hubiera finalizado.

+0

ReadAsStringAsync puede devolver "" si la secuencia de contenido ya se ha leído de (muy, muy probable). Use la solución de @ virender para asegurarse de leer siempre la transmisión desde la posición 0. – mikesigs

2

Si bien la respuesta otorgada se refería a ReadAsStringAsync, la respuesta no tenía ningún ejemplo. Seguí el consejo de gdp y obtuve un ejemplo algo funcional ...

Creé una única clase llamada MessageInterceptor. No hice más que derivar de ActionFilterAttribute e inmediatamente comenzó a interceptar las llamadas al método webAPI antes de que el controlador lo obtuviera, y después de que el controlador terminara. Aquí está mi clase final. Este ejemplo usa el Serializador XML para obtener tanto la solicitud como la respuesta en una cadena XML. Este ejemplo encuentra la solicitud y la respuesta como objetos poblados, esto significa que la deserialización ya se ha producido. La recopilación de datos de un modelo poblado y la serialización en una cadena XML es una representación de la solicitud y la respuesta, no de la solicitud y respuesta posteriores reales enviadas por IIS.

ejemplo de código - 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

No debe acceder directamente a .Result, bloquea, también quiere Async/Await the ReadAsStringAsync. – gdp

+1

gdp: no estoy seguro de entender sus comentarios "quiero Asnyc/aguardar el ReadAsStringAsync". OnActionExecuted ocurre después de que el controlador haya disparado y haya terminado. No hay nada que bloquear, o esperar, la respuesta completa está disponible ... – barrypicker

4

Utilice esta función para obtener el cuerpo de la solicitud en 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

Funciona para 'HttpActionExecutedContext', pero ¿qué pasa con' System.Web.Mvc.ActionExecutedContext'? –

0

Uso de abajo para leer la cadena de respuesta:

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; 
    } 
Cuestiones relacionadas