2012-04-23 1176 views
9

我已经创建了一个过滤器,它继承了asp.net web api中的System.Web.Http.Filters.ActionFilterAttribute,并且想要访问HttpActionExecutedContext结果对象中的一些数据。获取HttpActionExecutedContext结果值

在什么阶段/什么时候这个对象被填充?正如我在重写OnActionExecuted方法时所看到的那样,它始终为空?

任何想法?

编辑:

在我的自定义过滤器

例如这里:

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

    base.OnActionExecuted(context); 
} 
+0

分享一些码。您正在使用测试版还是源代码版本?这个对我有用。 – Aliostad 2012-04-23 22:03:12

+0

@Aliostad嗨,即时通讯使用测试版。你在用什么? – gdp 2012-04-24 05:38:31

+0

我正在使用相同的测试版。 – Aliostad 2012-04-24 08:39:04

回答

7

截止了对内容结果使用ReadAsStringAsync。 我正试图在实际请求完成之前访问属性。

+0

如果内容流已经被读取,很可能)。使用@Virender的解决方案,以确保您始终从位置0读取流。 – mikesigs 2016-10-27 22:37:15

2

虽然授予的答案指的是ReadAsStringAsync,但答案却没有例子。我遵循gdp的建议并衍生出一个有点可行的例子...

我创建了一个名为MessageInterceptor的类。除了派生自ActionFilterAttribute之外,我没有做任何事情,它在控制器获取它之前以及控制器完成之后立即开始拦截webAPI方法调用。这是我的最后一堂课。本示例使用XML序列化程序将请求和响应都转换为XML字符串。此示例将请求和响应作为填充对象进行查找,这意味着已经发生了反序列化。从已填充模型收集数据并序列化为XML字符串是请求和响应的表示 - 而不是IIS发回的实际发布请求和响应。

代码示例 - 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

您不应直接访问.Result,它会阻止,您还希望Async/Await ReadAsStringAsync。 – gdp 2013-07-28 21:52:14

+1

gdp - 不知道我理解你的意见“想要Asnyc /等待ReadAsStringAsync”。 OnActionExecuted发生在控制器已经触发并完成之后。没有什么可以阻止或等待 - 整个响应是可用的... – barrypicker 2013-07-29 01:07:11

4

使用此功能来获得的请求主体的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

它适用于'HttpActionExecutedContext',但是'System.Web.Mvc.ActionExecutedContext'是怎么回事? – 2017-07-19 10:51:44

0

用来读取响应字符串:

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