在WebApi控制器中阅读HttpContent

如何在MVC webApi控制器操作中读取PUT请求上的内容。

[HttpPut] public HttpResponseMessage Put(int accountId, Contact contact) { var httpContent = Request.Content; var asyncContent = httpContent.ReadAsStringAsync().Result; ... 

我在这里得到空string:(

我需要做的是:找出在初始请求中修改/发送的“什么属性”(意思是说,如果Contact对象有10个属性,而我只想更新其中的2个,则只发送两个属性,像这样的东西:

 { "FirstName": null, "LastName": null, "id": 21 } 

预期的最终结果是

 List<string> modified_properties = {"FirstName", "LastName"} 

通过devise,ASP.NET Web API中的主体内容被视为只能读取一次的只向前stream。

在您的案例中,第一次读取是在Web API绑定您的模型时完成的,之后, Request.Content将不会返回任何内容。

您可以从您的操作参数中删除contact ,获取内容并将其手动反序列化为对象(例如使用Json.NET):

 [HttpPut] public HttpResponseMessage Put(int accountId) { HttpContent requestContent = Request.Content; string jsonContent = requestContent.ReadAsStringAsync().Result; CONTACT contact = JsonConvert.DeserializeObject<CONTACT>(jsonContent); ... } 

这应该做的伎俩(假设accountId是URL参数,所以它不会被视为内容读取)。

您可以使用以下方法保留CONTACT参数:

 using (var stream = new MemoryStream()) { var context = (HttpContextBase)Request.Properties["MS_HttpContext"]; context.Request.InputStream.Seek(0, SeekOrigin.Begin); context.Request.InputStream.CopyTo(stream); string requestBody = Encoding.UTF8.GetString(stream.ToArray()); } 

为我返回我的参数对象的JSON表示,所以我可以用它来处理和loggingexception。

find答案在这里接受

即使这个解决scheme看起来很明显,我只是想在这里发布,所以下一个人会更快地谷歌。

如果您仍希望将模型作为方法中的参数,则可以创build一个DelegatingHandler来缓冲内容。

 internal sealed class BufferizingHandler : DelegatingHandler { protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { await request.Content.LoadIntoBufferAsync(); var result = await base.SendAsync(request, cancellationToken); return result; } } 

并将其添加到全局消息处理程序:

 configuration.MessageHandlers.Add(new BufferizingHandler()); 

这个解决scheme是基于Darrel Miller的回答 。

这样所有的请求将被缓冲。

读取任何请求内容的最简单方法通常是使用像fiddler这样的http代理

这有很大的好处,显示你所有的本地stream量(加上完整的请求 – 头等)和许多其他请求,读取特定控制器中的特定操作内的请求内容将不会显示你 – 例如401/404等。

您也可以使用fiddler的composer php从头开始创buildtesting请求,或者修改以前的请求。

如果你出于某种原因不能使用代理服务器,或者必须从Web应用程序内部查看请求,那么这个答案看起来是明智的