2015-12-22 43 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