【问题标题】:Getting the HttpActionExecutedContext Result values获取 HttpActionExecutedContext 结果值
【发布时间】:2012-04-23 21:30:36
【问题描述】:

我创建了一个过滤器,它继承了 asp.net web api 中的 System.Web.Http.Filters.ActionFilterAttribute 并希望访问 HttpActionExecutedContext 结果对象中的一些数据。

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

有什么想法吗?

编辑:

例如在我的自定义过滤器中:

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

    base.OnActionExecuted(context);
}

【问题讨论】:

  • 分享一些代码。您使用的是 beta 版本还是源代码版本?它对我有用。
  • @Aliostad 您好,我正在使用测试版。你在用什么?
  • 我正在使用相同的测试版。
  • @Aliostad 很奇怪。当你说它对你有用时,你能再澄清一点吗,即使用来自 system.web.http.filters 等的相同 onactionexecuted 事件。

标签: asp.net-web-api action-filter


【解决方案1】:

使用此函数在 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;
}

【讨论】:

  • 它适用于HttpActionExecutedContext,但System.Web.Mvc.ActionExecutedContext 呢?
【解决方案2】:

最终对内容结果使用 ReadAsStringAsync。 我试图在实际请求完成之前访问该属性。

【讨论】:

  • ReadAsStringAsync 可能会返回 "" 如果 Content 流已经被读取(非常非常有可能)。使用@virender 的解决方案确保您始终从位置 0 读取流。
【解决方案3】:

虽然授予的答案提到了 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;
        }
    }
}

【讨论】:

  • 您不应该直接访问 .Result,它会阻塞,您还想异步/等待 ReadAsStringAsync。
  • gdp - 不确定我是否理解您的 cmets“想要 Asnyc/等待 ReadAsStringAsync”。 OnActionExecuted 在控制器触发并完成后发生。没有什么可以阻止或等待 - 整个响应都可用...
【解决方案4】:

使用下面读取响应字符串:

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

【讨论】:

    猜你喜欢
    • 2014-10-08
    • 1970-01-01
    • 2020-01-30
    • 2012-09-10
    • 2013-12-31
    • 1970-01-01
    • 1970-01-01
    • 2010-09-06
    • 1970-01-01
    相关资源
    最近更新 更多