添加MessageHandler后HttpContext为null

本文关键字:null HttpContext MessageHandler 添加 | 更新日期: 2023-09-27 18:27:50

我正在开发一个WebAPI,并收到了如下POST数据:

[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());

在我的web.config中,我已经尝试添加

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

有没有办法坚持这个方法,而不是创建一个日志例程并从每个函数调用它?

添加MessageHandler后HttpContext为null

需要明确的是,HttpContext不能为null,它是静态的。那么HttpContext.Current为空吗?或者我的猜测是HttpContext.Current.Request.InputStream为空。Webapi会自动读取流并对其进行处理,并将帖子正文反序列化为您的操作输入。因此,您应该将WebApi操作编码为如下内容:

[HttpPost]
public Int16 Foo(Model_Deserialized model)
{
    ...
}