2012-04-23 1177 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; 
    }