Asp.net web api HttpWebRequest完成大文件流传输之前的Web API Post hit

Asp.net web api HttpWebRequest完成大文件流传输之前的Web API Post hit,asp.net-web-api,Asp.net Web Api,在我们的应用程序(Silverlight 5浏览器外客户端访问WebApi服务器)中,我们经常使用HttpClient发布/获取/删除客户端和服务器之间的所有实体。这在大多数情况下都可以正常工作,但最近我们在上传(发布)更大的实体(>30/35mb)时遇到了一个问题:我们启动流处理,在完成之前,我们在Web API上的Post方法被命中,接收到一个空实体 我们无法理解发生了什么,并且怀疑一定有一些与时间相关的问题,因为这一切都取决于上传的大小 为了进一步解释,我们的客户总结如下: HttpRes

在我们的应用程序(Silverlight 5浏览器外客户端访问WebApi服务器)中,我们经常使用HttpClient发布/获取/删除客户端和服务器之间的所有实体。这在大多数情况下都可以正常工作,但最近我们在上传(发布)更大的实体(>30/35mb)时遇到了一个问题:我们启动流处理,在完成之前,我们在Web API上的Post方法被命中,接收到一个空实体

我们无法理解发生了什么,并且怀疑一定有一些与时间相关的问题,因为这一切都取决于上传的大小

为了进一步解释,我们的客户总结如下:

HttpResponseMessage response = await _client.SendAsync(request);
string jsonResult = await response.Content.ReadAsStringAsync();
。。。其中uclient是我们的HttpClient,请求我们的HttpRequestMessage。如果它也是相关的(我尽量不让问题充斥代码:),那么请求中的内容如下所示:

request.Content = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, "application/json");
好的,当我们调试这个方法时,服务器上的Post方法在Wait_client.SendAsync(请求)完成之前被命中,这在某种程度上“解释”了为什么它在这种情况下(较大的实体)接收空实体,当它工作时,等待调用完成,然后命中Post

如果由于HttpClient上的某些限制(关于AllowWriteStreamBuffering的访问),if对它有更多的了解,我们还测试了一个等效的场景,但直接使用HttpWebRequest。。。不幸的是,行为完全相同。以下是相关摘录:

httpRequest.BeginGetRequestStream(RequestStreamCallback, httpRequest);
(其中httpRequest是我们的HttpWebRequest,AllowWriteStreamBuffering=false),处理请求流的回调如下所示:

private void RequestStreamCallback(IAsyncResult ar)
{
   var request = ar.AsyncState as System.Net.HttpWebRequest;
   if (request != null)
   {
      var requestStream = request.EndGetRequestStream(ar);
      var streamWriter = new StreamWriter(requestStream) {AutoFlush = true};
      streamWriter.Write(_jsonContent);
      streamWriter.Close();
      requestStream.Close(); // Belt and suspenders... shouldn't be needed

      // Make async call for response
      request.BeginGetResponse(ResponseCallback, request);
   }
}
同样,对于较大的实体,当我们调试Web API上的Post方法时,会在streamWriter.Write完成并命中streamWriter.Close之前命中(带有空参数)


我们已经读遍了所有的地方,并为此奋斗了好几天。任何帮助都将不胜感激

万一有人碰到这件事,我终于弄明白了到底发生了什么

本质上,Web API Post方法中的模型绑定机制在对JSON进行反序列化时抛出异常,但异常多少有些“隐藏”。。。至少如果您不太了解Web API的内部工作原理,就像我的情况一样

我的Post方法最初缺少此验证检查:

var errors = "";
if (!ModelState.IsValid)
{
  foreach (var prop in ModelState.Values)
  {
    foreach (var modelError in prop.Errors.Where(modelError => modelError != null))
    {
     if (modelError.Exception != null)
     {
       errors += "Exception message: " + modelError.Exception.Message + Environment.NewLine;
       errors += "Exception strack trace: " + modelError.Exception.StackTrace + Environment.NewLine;
     }
     else
       errors += modelError.ErrorMessage + Environment.NewLine;

     errors += " --------------------- " + Environment.NewLine + Environment.NewLine;
   }
 }

 return Request.CreateErrorResponse(HttpStatusCode.NoContent, errors);
}
这是一个“样本”检查,主要目的是验证ModelState的有效性。。。在我们的中断场景中,is无效,因为Web API无法绑定实体,原因可以在ModelState.Values的Errors属性中找到。正如前面提到的,Post被点击是正常的,但是有一个空实体

顺便说一句,问题主要是因为我们没有真正的流式传输内容,而是使用了一个试图完全反序列化的StringContent。。。但这是另一个故事,我们在这里主要关心的是不了解发生了什么以及在哪里

希望这有帮助