首页 > 解决方案 > 在 HttpResponseMessage 中返回任何内容都不会导致服务器端 Web 服务调用延迟

问题描述

我从 .Net 3.5 Framework 客户端调用 2 个 Web 服务(服务器是更现代的 .NET Framework Server:4.6)。

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

经过大量测试后,我可以将其简化为导致问题的第一种方法“DownloadFile”。并且总是当我从它返回状态码以外的任何其他内容时(内容与否都无关紧要)。

我对这种现象完全不知所措(我原以为客户端会遇到麻烦,但是服务器直到几分钟后才输入那个代码部分看起来服务器本身陷入了麻烦,这是出乎意料的,也是出乎意料的是第二种方法而不是原来的方法在那里遇到了问题)。

所以我的问题是为什么返回除了 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");

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
    }
}

标签: c#asp.net

解决方案


我的理论是,当您从服务器获得错误响应时,不会创建文件。假设您正在捕获 DownloadFile 异常,当您返回除 OK 以外的任何其他响应时,您应该收到该异常。

GetFileLength 可能会返回一个无效的数字,根据这个答案,它可能会导致您提到的错误。至于为什么需要 6 分钟才能到达该服务器代码 - 我猜它在调用该方法之前做了一些内部错误处理,并返回一个错误。遗憾的是 ASP.net 4.* 不是开源的,所以我不太熟悉内部工作原理。


推荐阅读