2015-12-22 40 views
1

我開發的WebAPI,並已接受這樣的我POST數據後,爲空:的HttpContext添加了MessageHandler

[HttpPost] 
     public Int16 Foo() 
     { 
      var input = new StreamReader(HttpContext.Current.Request.InputStream).ReadToEnd(); 
      Model_Deserialized model = JsonConvert.DeserializeObject<Model_Deserialized>(input); 
      ... 
     } 

最近,我覺得有必要記錄都在那裏,正在發送的請求。我試圖使用在http://weblogs.asp.net/fredriknormen/log-message-request-and-response-in-asp-net-webapi建議的方法,但在執行這些步驟後,我的輸入變量開始是一個空字符串。

這是我的消息處理程序看起來像

public abstract class MessageHandler : DelegatingHandler 
    { 
     protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
     { 
      var corrId = string.Format("{0}{1}", DateTime.Now.Ticks, Thread.CurrentThread.ManagedThreadId); 
      var requestInfo = string.Format("{0} {1}", request.Method, request.RequestUri); 

      var requestMessage = await request.Content.ReadAsByteArrayAsync(); 

      String ip; 

      if (request.Properties.ContainsKey("MS_HttpContext")) 
      { 
       var ctx = request.Properties["MS_HttpContext"] as HttpContextWrapper; 
       if (ctx != null) 
       { 
        ip = ctx.Request.UserHostAddress; 
       } 
      } 

      else 
      { 
       ip = "error"; 
      } 

      await IncommingMessageAsync(corrId, requestInfo, requestMessage, ip); 

      var response = await base.SendAsync(request, cancellationToken); 

      return response; 
     } 


     protected abstract Task IncommingMessageAsync(string correlationId, string requestInfo, byte[] message, String ip); 
    } 

,這是我MessageLoggingHandler

public class MessageLoggingHandler : MessageHandler 
    { 
     protected override async Task IncommingMessageAsync(string correlationId, string requestInfo, byte[] message, String ip) 
     { 
      await Task.Run(() => 
       WriteToFile(ip + "{" + correlationId + "} - Request: {" + requestInfo + "}\r\n{" + Encoding.UTF8.GetString(message) + "}")); 
     } 


     private void WriteToFile(string text) 
     { 
      string path = "C:\\Logs\\ServiceLog" + DateTime.Now.Year + "-" + DateTime.Now.Month + "-" + DateTime.Now.Day + ".txt"; 
      using (StreamWriter writer = new StreamWriter(path, true)) 
      { 
       writer.WriteLine(DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt") + "--" + text); 
       writer.Close(); 
      } 
     } 
    } 

我也添加到了我的Global.asax

GlobalConfiguration.Configuration.MessageHandlers.Add(new MessageLoggingHandler()); 

在我的網站.config我已經嘗試加入

<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> 
<compilation debug="true" targetFramework="4.5"> 

有沒有辦法堅持這種方法,而不是創建一個日誌程序,並從每個函數調用它?

回答

0

只是要清楚HttpContext不能爲空 - 它是靜態的。那麼HttpContext.Current爲空?或者我的猜測是HttpContext.Current.Request.InputStream爲空。 Web api會自動讀取流並處理它,並將後主體反序列化爲動作輸入。所以,你應該像下面的網頁API操作代碼的東西:

[HttpPost] 
public Int16 Foo(Model_Deserialized model) 
{ 

    ... 
} 
+0

我想補充 - 網頁API抽象了序列化/反序列化的多數情況下,所以在大多數情況下,你不應該做手工反序列化。 – Padraic

+0

此WebAPI適用於移動應用程序。我曾經在應用程序中序列化數據並在api中進行反序列化,是否應該將數據作爲模型發送? – Caio

+0

另外...這是否意味着如果我的MessageHandler在我的控制器之前讀取InputStream,它只是處理內容?直接反序列化的方法是否可以解決這個問題? – Caio