2015-12-22 10 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, но после выполнения этих шагов моя входная переменная стала пустой строкой.

Это как мой Message Handler выглядит

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 null? ИЛИ я предполагаю, что HttpContext.Current.Request.InputStream имеет значение null. Web api автоматически считывает поток и распределяет его и десериализует тело сообщения для ввода вашего действия. Таким образом, вы должны кодировать свои действия Web Api к чему-то вроде следующего:

[HttpPost] 
public Int16 Foo(Model_Deserialized model) 
{ 

    ... 
} 
+0

Просто добавить - Web Api абстрагирует большинство случаев сериализации/де-сериализации поэтому в большинстве случаев вы не должны делать ручной Десериализация. – Padraic

+0

Этот WebAPI предназначен для мобильного приложения. Я использовал для сериализации данных в приложении и десериализации в api, должен ли я просто отправлять данные в качестве модели? – Caio

+0

Также ... это означает, что если мой MessageHandler читает InputStream перед моим контроллером, он просто располагает содержимым? Может ли метод прямого десериализации решить эту проблему? – Caio