简体   繁体   English

.net API 尝试接受带有大文件的 model 时出错

[英].net API error when attempting to accept model with large file

I have an API method that receives a null model parameter when a large file is passed to it.我有一个 API 方法,当一个大文件传递给它时,它接收一个 null model 参数。
I created a test client to test this endpoint.我创建了一个测试客户端来测试这个端点。 Both the test client and the API have these same identical models and are using .NET 4.5:测试客户端和 API 都具有相同的型号,并且使用的是 .NET 4.5:

public class FilingPostModel
    {
        public string Id { get; set; }
        public string TypeId { get; set; }
        public string FirstName { get; set; }
        public string MiddleName { get; set; }
        public string LastName { get; set; }
        public string Suffix { get; set; }
        public string Line1 { get; set; }
        public string Line2 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string PostalCode { get; set; }
        public string Country { get; set; }
        public string Email { get; set; }
        public string PhoneNumber { get; set; }
        public string Comment { get; set; }
        public string DateSubmitted { get; set; }
        public string Summary { get; set; }
        public List<FilePostModel> FileData { get; set; }
    }

    public class FilePostModel
    {
        public string FileId { get; set; }
        public string FileName { get; set; }
        public string ContentType { get; set; }
        public string FileContent { get; set; }
        public string DateSubmitted { get; set; }
        public string ClassificationId { get; set; }     
    }

The test client is submitting this model:测试客户端正在提交此 model:

City: "j"
Comment: null
Country: "United States"
Email: "test@test.tst"
FileData: Count = 1
TypeId: "f94e264a-c8b1-44aa-862f-e6f0f7565e19"
FirstName: "fname"
Id: null
LastName: "lname"
Line1: "testdrive 1"
Line2: null
MiddleName: null
PhoneNumber: "3748923798"
PostalCode: "12345"
State: "Pennsylvania"
Suffix: null
Summary: null

The FileData component has one item: FileData 组件有一项:

FileContent: "xY+v6sC8RHQ19av2LpyFGu6si8isrn8YquwGRAalW/6Q..."
ClassificationId: null
ContentType: "text/plain"
FileName: "large.txt"

This is the test clients method used to create and send the API request这是用于创建和发送 API 请求的测试客户端方法

public async Task<ActionResult> PostNewFiling(FilingPostModel model)
{
    Dictionary<string, string> req = new Dictionary<string, string>
        {
            {"grant_type", "password"},
            {"username", "some user name"},
            {"password", "some password"},
        };
    FilingApiPostModel postModel = new FilingApiPostModel(model);
    using (HttpClient client = new HttpClient())
    {
        client.Timeout = TimeSpan.FromMinutes(15);
        client.BaseAddress = new Uri(baseUrl);
        var resp = await client.PostAsync("Token", new FormUrlEncodedContent(req));
        if (resp.IsSuccessStatusCode)
        {
            TokenModel token = JsonConvert.DeserializeObject<TokenModel>(await resp.Content.ReadAsStringAsync());
            if (!String.IsNullOrEmpty(token.access_token))
            {
                foreach (HttpPostedFileBase file in model.Files)
                {
                    if (file != null)
                    {                                    
                        FilePostModel fmodel = new FilePostModel();
                        fmodel.FileName = file.FileName;
                        fmodel.ContentType = file.ContentType;
                        byte[] fileData = new byte[file.ContentLength];
                        await file.InputStream.ReadAsync(fileData, 0, file.ContentLength);
                        fmodel.FileContent = Convert.ToBase64String(fileData);
                        fmodel.ClassificationId = model.Classification1;
                        postModel.FileData.Add(fmodel);
                    }
                }
                
                client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token.access_token);
                var response = await client.PostAsJsonAsync("api/Filing/PostFiling", postModel);    
                var responseBody = await response.Content.ReadAsStringAsync();

                if (response.IsSuccessStatusCode)
                    return Json(new { responseBody });
                else
                    return Json(new { error = true, message = "Error Uploading", obj = responseBody });
            }
        }
        return Json(new { error = true, message = "Error Uploading" });
    }
}

Here is the API method to receive this client request:这是接收此客户端请求的 API 方法:

public async Task<StatusModel> PostFiling(FilingPostModel model)

Here is the maxAllowedContentLength setting in web.config:这是 web.config 中的 maxAllowedContentLength 设置:

<system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="4294967295" />
      </requestFiltering>
    </security>
  </system.webServer>

The API model is always null in this test scenario.在此测试场景中,API model 始终为null I'm receiving two types of errors:我收到两种类型的错误:

  1. Newtonsoft.Json - Array dimensions exceeded supported range Newtonsoft.Json - 阵列尺寸超出支持范围
  2. Newtonsoft.Json - Unexpected character encountered while parsing value: x. Newtonsoft.Json - 解析值时遇到意外字符:x。 Path 'FileData[0].Bytes', line 1, position 517路径 'FileData[0].Bytes',第 1 行,position 517

在此处输入图像描述

The file size of this test file is 560 MB.该测试文件的文件大小为 560 MB。 I used Dummy File Creator to create it.我使用Dummy File Creator来创建它。 Here's a sample of what the content looks like:以下是内容的示例:

ůêÀ¼Dt5õ«ö.œ…Ȭ®ªìD¥[þ6\hW åz·cʾYP¸‡>•;,–@Ó¶ÿm™­fø@ÃNÇIäÀ¿Y4~ëÆÃc¥EWÀ_÷õ9%«éÀG!WBÍ*G2P×æŸ7ú‚{ÓêRúÅîµMZSªšpt6ä”Òø˜H

I have also tried using "fsutil file createnew" to create a test file but receive similar error.我也尝试过使用“fsutil file createnew”来创建一个测试文件,但收到类似的错误。

Everything works properly when testing with a 256 MB file.使用 256 MB 文件进行测试时,一切正常。

Thank you for your help.谢谢您的帮助。

you can add two attributes to your action:您可以为您的操作添加两个属性:

[RequestFormLimits(MultipartBodyLengthLimit = 209715200)]
[FromBody]

If you need to post JSON I would change your FileData object to use a Base64 encoded string in place of the byte array.如果您需要发布 JSON 我会更改您的 FileData object 以使用 Base64 编码字符串代替字节数组。

Change the Bytes property in FileData to a string and then when creating the request change fmodel.Bytes = fileData to fmodel.Bytes = Convert.ToBase64String(fileData) .将 FileData 中的Bytes属性更改为字符串,然后在创建请求时将fmodel.Bytes = fileData更改为fmodel.Bytes = Convert.ToBase64String(fileData)

After deserialising your JSON you can convert the base64 back to a byte[] using Convert.FromBase64String(String) .反序列化 JSON 后,您可以使用Convert.FromBase64String(String)将 base64 转换回 byte[] 。

Not only will this prevent you exceeding the array limit in JSON but will also reduce the payload size considerably.这不仅会阻止您超出 JSON 中的数组限制,而且还会大大减少有效负载大小。

Every implementation has its own limit for example PHP has 2MB by default you can increase it using Post_Max_Size每个实现都有自己的限制,例如 PHP 默认有 2MB,您可以使用 Post_Max_Size 增加它

ASP.NET Core enforces 30MB any file bigger than default limitation can cause errors. ASP.NET 内核强制执行 30MB 大于默认限制的任何文件都可能导致错误。

Here's Upload Large Files In ASP.NET Core !这是在 ASP.NET 内核中上传大文件

For IIS Express, you need to add web.config to your project and add the following markup into it:对于 IIS Express,您需要将 web.config 添加到您的项目中,并在其中添加以下标记:

<system.webServer>
  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="209715200" />
    </requestFiltering>
  </security>
</system.webServer>

If the issue is being caused by the total size of the array, rather than the number of elements in the array, the OutOfMemoryException might be avoided by targeting 64-bit compilation and by updating your app.config:如果问题是由数组的总大小而不是数组中的元素数量引起的,则可以通过针对 64 位编译和更新 app.config 来避免OutOfMemoryException

<configuration>
  <runtime>
    <gcAllowVeryLargeObjects enabled="true" />
  </runtime>
</configuration>

gcAllowVeryLargeObjects element gcAllowVeryLargeObjects 元素

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 获取 ML NET 模型 zip 文件流时 Blazor 中的错误 - Error In Blazor When Getting Stream of ML NET Model zip file 尝试使用 .NET EF 进行迁移时,值不能是 null 错误 - Value cannot be null error when attempting migration w/ .NET EF 如何接受文件上传和一些数据作为对.NET REST API的POST - How to accept a file upload AND some data as a POST to a .NET REST API 尝试执行本地主机 API 时,在 ReactJS 应用程序中出现 CORS 错误 - Getting CORS error in ReactJS app when attempting to execute localhost API 尝试将文件保存到独立存储时,如果没有网络连接,则显示错误消息 - Give error if there is no network connection when attempting to save file to isolated storage Web API大文件发布OutOfMemoryException错误 - Web API large File Post OutOfMemoryException error ASP.NET - 上传非常大的文件时无法立即获得错误响应? - ASP.NET - Cannot get error response immediately when uploading very large file? ASP.NET Web API-尝试传递参数时不支持GET HTTP Verb(405) - ASP.NET Web API - GET HTTP Verb not supported (405) when attempting to pass a parameter 尝试将目录上载到S3时出现NullReferenceException(.NET API - C#) - NullReferenceException when attempting to upload directory to S3 (.NET API - C#) .Net core api 在保存大文件时返回 404 - .Net core api returns 404 while saving large file
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM