在HttpResponseMessage中返回任何内容但ok都会导致服务器端Web服务调用延迟

Tho*_*mas 10 c# asp.net

我从.Net 3.5 Framework Client调用2个webservices(Server是一个更现代的.NET Framework Server:4.6).

分开我遇到没有问题,但是如果我按照下面显示的顺序调用方法,我得到的问题是服务器上的VerifyFile方法永远不会输入,而是我立即得到一个服务器已经提交了协议Violation Section = ResponseStatusLine错误在客户端上.更确切地说:服务器在事件中注册VerifyFile请求但直到最多6分钟后才输入实际代码(并且立即返回导致上述错误的内容).

经过多次测试后,我可以将其减少到第一种方法"DownloadFile"是问题的原因.总是当我从状态代码中返回任何其他内容时(内容与否无关紧要).

我完全失去了这种现象(我本来希望客户有麻烦,但是服务器没有进入那个代码部分,直到MINUTES后来看起来服务器正在进入麻烦本身,这是意料之外的,也是出乎意料的是SECOND方法而不是原始方法遇到了问题.

所以我的问题是为什么返回除了HttpStatusCode.OK之外的任何内容导致这些问题以及我该怎么做才能纠正这个问题?

客户:

WebClient webClient = new WebClient();
webClient.QueryString.Add("downloadId", id);
webClient.DownloadFile("localhost/Download/DownloadFile", @"c:\temp\local.txt");
webClient = new WebClient();
webClient.QueryString.Add("downloadId", id);
webClient.QueryString.Add("fileLength", GetFileLength(@"c:\temp\local.txt"));
var i = webClient.DownloadString("localhost/Download/VerifyFile");
Run Code Online (Sandbox Code Playgroud)

Testwise我将DownloadFile替换为: webClient.DownloadString("localhost/Download/DownloadFile");

最初我也只有一个新的WebClient,但在第一次失败后添加了第二个.

服务器:

[RoutePrefix("Download")]
public class DownloadController : ApiController
{
    [HttpGet]
    [Route("DownloadFile")]
    public IHttpActionResult DownloadFile(int downloadId){
        return ResponseMessage(GetFile(downloadId));
    }

    private HttpResponseMessage GetFile(int downloadId){
        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);

        string filePath = GetFilePathFromDB(downloadid);

        if (filePath != String.Empty){
            var stream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite);
            result.Content = new StreamContent(stream);
            result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
            result.Content.Headers.ContentDisposition.FileName = Path.GetFileName(filePath);
            result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
            result.Content.Headers.ContentLength = stream.Length;   
        }
        else{
            result = new HttpResponseMessage(HttpStatusCode.InternalServerError);
        }       
        return result;
    }

    [HttpGet]
    [Route("VerifyFile")]
    public IHttpActionResult VerifyFile(int downloadId, int fileLength)
    {
        return Content(HttpStatusCode.OK, "OK");
    }


    private string GetFilePathFromDB(int downloadId)
    {
         return @"C:\temp\mytest.txt"; // testcode
    }
}
Run Code Online (Sandbox Code Playgroud)

ATe*_*rry 1

你可以尝试三件事。

  1. 遵循 http 规范,这样就不会出现此错误

  2. 将其添加到您的客户端 web.config

    <system.net>
       <settings>
         <httpWebRequest useUnsafeHeaderParsing="true" />
       </settings>
    </system.net>
    
    Run Code Online (Sandbox Code Playgroud)
  3. 将连接标头设置为关闭而不是保持活动状态

    class ConnectionCloseClient : WebClient
    {
        protected override WebRequest GetWebRequest(Uri address)
        {
            WebRequest request = base.GetWebRequest(address);
            if (request is HttpWebRequest)
            {
                (request as HttpWebRequest).KeepAlive = false;
            }
            return request;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)