Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET-上载非常大的文件时无法立即获得错误响应?_C#_Asp.net Core_Postman - Fatal编程技术网

C# ASP.NET-上载非常大的文件时无法立即获得错误响应?

C# ASP.NET-上载非常大的文件时无法立即获得错误响应?,c#,asp.net-core,postman,C#,Asp.net Core,Postman,当我使用Postman尝试将一个大文件上载到我的服务器(用.NET Core 2.2编写)时,Postman立即显示HTTP错误404.13-找不到错误:请求过滤模块配置为拒绝超过请求内容长度的请求 但是当我用我的代码上传那个大文件时,它在发送文件的时候被卡住了 我的客户代码: public async void TestUpload() { StreamContent streamContent = new StreamContent(File.OpenRead("D:

当我使用Postman尝试将一个大文件上载到我的服务器(用.NET Core 2.2编写)时,Postman立即显示
HTTP错误404.13-找不到
错误:
请求过滤模块配置为拒绝超过请求内容长度的请求

但是当我用我的代码上传那个大文件时,它在发送文件的时候被卡住了

我的客户代码:

    public async void TestUpload() {
        StreamContent streamContent = new StreamContent(File.OpenRead("D:/Desktop/large.zip"));
        streamContent.Headers.Add("Content-Disposition", "form-data; name=\"file\"; filename=\"large.zip\"");
        MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent();
        multipartFormDataContent.Add(streamContent);
        HttpClient httpClient = new HttpClient();
        Uri uri = new Uri("https://localhost:44334/api/user/testupload");
        try {
            HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(uri, multipartFormDataContent);
            bool success = httpResponseMessage.IsSuccessStatusCode;
        }
        catch (Exception ex) {

        }
    }
我的服务器代码:

    [HttpPost, Route("testupload")]
    public async Task UploadFile(IFormFileCollection formFileCollection) {
        IFormFileCollection formFiles = Request.Form.Files;
        foreach (var item in formFiles) {
            using (var stream = new FileStream(Path.Combine("D:/Desktop/a", item.FileName), FileMode.Create)) {
                await item.CopyToAsync(stream);
            }
        }
    }
我的客户端代码在服务器未接收到任何请求(我使用断点确保)的情况下,卡在行
HttpResponseMessage HttpResponseMessage=wait httpClient.PostAsync(uri,multipartFormDataContent)

如果文件较大,它会被卡住更长时间。查看TaskManager,我可以看到我的客户机程序在实际将文件上载到服务器时消耗了大量CPU和磁盘。过了一会儿,代码移到下一行

bool success = httpResponseMessage.IsSuccessStatusCode
然后通过阅读回复内容,我得到了邮递员的准确结果

现在我想知道如何立即得到错误,以便能够及时通知用户,我不想等待太久

请注意,当我使用Postman上传大文件时,我的服务器也不会收到任何请求。我想我遗漏了一些东西,也许我的客户端代码有问题

编辑:实际上我认为这是客户端错误。但如果这是服务器端错误,那么对我来说仍然没有太大意义。因为,让我澄清我的想法。我想创建这个可以跨项目使用的小助手类,也许我也可以与我的朋友共享。所以我认为它应该能够像邮递员一样,尽快确定错误。如果邮递员能做到,我也能


EDIT2:奇怪的是,今天我发现Postman事先不知道服务器是否接受大请求,我上传了一个大文件,我看到它实际上将整个文件发送到服务器,直到服务器得到响应。现在我不再相信自己了,为什么我认为邮递员提前知道了错误,我一定很愚蠢。但这确实意味着我找到了一种比邮递员做得更好的方法,因此我认为这个问题可能对某些人有用。

您的问题与服务器端C代码无关。您的请求被卡住是因为客户端和服务器之间发生了什么(所谓“服务器”,我指的是IIS、Apache、Nginx…,而不是您的服务器端代码)

在HTTP中,大多数客户端在发送所有请求数据之前不会读取响应。因此,即使服务器发现请求太大并返回错误响应,客户端也不会读取响应,直到服务器接受整个请求


当涉及到服务器端时,您可以进行检查,但我认为在将文件发送到服务器之前,通过检查文件大小(这基本上是邮递员在您的情况下所做的),在客户端处理它会更方便。

现在我可以做我想做的事情了。但首先我要感谢你@Marko Papic,你的信息确实帮助我思考一种方法来做我想做的事

我正在做的是:

  • 首先,创建一个空的
    ByteArrayContent
    请求,其中包含要上载到服务器的文件的
    ContentLength
  • 其次,在
    try catch
    块中环绕
    HttpResponseMessage=wait HttpClient.SendAsync(HttpRequestMessage)
    catch
    块捕获
    HttpRequestException
    ,因为我正在发送一个文件长度的请求,但我的实际内容长度为0,因此它将抛出一个
    HttpRequestException
    ,并显示消息
    在写入所有字节之前无法关闭流
  • 如果代码到达
    catch
    块,则表示服务器允许文件大小或更大的请求。如果没有异常且代码移到下一行,则如果
    HttpResponseMessage.StatusCode
    404,则表示服务器拒绝大于文件大小的请求。
    HttpResponseMessage.StatusCode
    而非404的情况永远不会发生(不过我不确定这一点)
  • 到目前为止,我的最终代码是:

        private async Task<bool> IsBigRequestAllowed() {
            FileStream fileStream = File.Open("D:/Desktop/big.zip", FileMode.Open, FileAccess.Read, FileShare.Read);
            if(fileStream.Length == 0) {
                fileStream.Close();
                return true;
            }
            HttpRequestMessage = new HttpRequestMessage();
            HttpMethod = HttpMethod.Post;
            HttpRequestMessage.Method = HttpMethod;
            HttpRequestMessage.RequestUri = new Uri("https://localhost:55555/api/user/testupload");
            HttpRequestMessage.Content = new ByteArrayContent(new byte[] { });
            HttpRequestMessage.Content.Headers.ContentLength = fileStream.Length;
            fileStream.Close();
            try {
                HttpResponseMessage = await HttpClient.SendAsync(HttpRequestMessage);
                if (HttpResponseMessage.StatusCode == HttpStatusCode.NotFound) {
                    return false;
                }
                return true; // The code will never reach this line though
            }
            catch(HttpRequestException) {
                return true;
            }
        }
    
    private异步任务IsBigRequestAllowed(){
    FileStream FileStream=File.Open(“D:/Desktop/big.zip”,FileMode.Open,FileAccess.Read,FileShare.Read);
    如果(fileStream.Length==0){
    fileStream.Close();
    返回true;
    }
    HttpRequestMessage=新的HttpRequestMessage();
    HttpMethod=HttpMethod.Post;
    HttpRequestMessage.Method=HttpMethod;
    HttpRequestMessage.RequestUri=新Uri(“https://localhost:55555/api/user/testupload");
    HttpRequestMessage.Content=newbyteArrayContent(新字节[]{});
    HttpRequestMessage.Content.Headers.ContentLength=fileStream.Length;
    fileStream.Close();
    试一试{
    HttpResponseMessage=等待HttpClient.SendAsync(HttpRequestMessage);
    if(HttpResponseMessage.StatusCode==HttpStatusCode.NotFound){
    返回false;
    }
    return true;//但是代码永远不会到达此行
    }
    捕获(HttpRequestException){
    返回true;
    }
    }
    
    注意:注意我的方法仍然存在问题。我的代码的问题是
    ContentLength
    属性,它不应该是文件的精确长度,应该更大。例如,如果我的文件长度正好为1000字节,那么如果文件成功上载到服务器,则服务器获得的
    请求
    具有更大的
    ContentLength
    值。因为
    HttpClient
    不仅仅发送文件的内容,它还必须发送许多信息。它必须发送边界