发布大文件 React.js &.net 5 [英] Posting large file React.js & .net 5

查看:28
本文介绍了发布大文件 React.js &.net 5的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 .net 5 API,它有一个端点,它接受由 IFormFile 文件、字符串描述和字符串名称组成的模型.

当使用 axios 从我的 react 客户端发布表单时,使用 55.500kb 文件一切正常,但是当发布 250,000kb 文件时,请求似乎让客户端没有任何问题,但当端点为空时,整个请求为空命中.

我的 API 端点使用 2147483648 的 RequestSizeLimit 进行修饰,并在 web.config 中进行了镜像.

我猜测原因是发布的文件太大,但不能 100% 确定.如果这是我需要以某种方式流式传输或分块请求的原因,还是其他原因导致此问题?

React 函数以发布表单:

 handleSubmit = async() =>{this.setState({ componentState: LOADING }, async () => {let form = new FormData();form.append(title", this.state.title);form.append(reference", this.state.reference);form.append("description", this.state.description);form.append(price", this.state.price);form.append(scormFile", this.state.file);让响应 = 等待 uploadCourseAsync(form);如果(响应.isSuccessStatusCode){this.setState({ componentState: SUCCESS });}别的 {this.setState({ 错误: response.errors })}})}

.net 端点接收请求:

 [RequestSizeLimit(2147483648)][HttpPost(上传课程")]公共异步任务UploadCourse([FromForm] CreateCourseCommand 命令){var ms = new MemoryStream();等待 command.ScormFile.CopyToAsync(ms);var byteArrayContent = new ByteArrayContent(ms.ToArray());var multipartContent = 新的 MultipartFormDataContent{{byteArrayContent, command.ScormFile.Name, command.ScormFile.FileName},{new StringContent(command.Description), "Description"},{new StringContent(command.Reference), "Reference"},{new StringContent(command.Price), "Price"},{new StringContent(command.Title), "Title"},{new StringContent(User.Claims.FirstOrDefault(c => c.Type == "Id")?.Value ?? string.Empty), "UploadedById"},{byteArrayContent, command.ScormFile.Name, command.ScormFile.FileName}};var url = _serviceUrlConfig.CourseService + "/course/uploadcourse";var myHttpClient = new HttpClient();var response = await myHttpClient.PostAsync(url, multipartContent);返回确定(响应);}

任何建议都会很棒,提前致谢.

解决方案

POST message max.大小通常被 http 服务器限制为 2 GB.此代码允许您下载任何大小的文件.

反应组件:

import React, { useState } from 'react';从 'uuid' 导入 { v4 as uuid };导出默认函数 LargeFileUploader(props) {const BYTES_PER_CHUNK = 10485760;//10MB 块大小.变量开始;变量部分;无功尺寸 = 0;无功xhr;var fileGuid = '';const [file, setFile] = useState('');函数发送请求(){大小 = 文件大小;开始 = 0;部分 = 0;xhr = 新的 XMLHttpRequest();xhr.addEventListener(加载",uploadComplete,false);上传文件(部分);}函数上传文件(){var blobFile = file.slice(start, BYTES_PER_CHUNK + start);var fd = new FormData();fd.append(文件", blobFile);fd.append(fileguid", fileGuid);fd.append('part', part);fd.append('rawFileName', file.name);fd.append('partsTotal', Math.ceil(SIZE/BYTES_PER_CHUNK));var url = process.env.PUBLIC_URL + "/";+ '文件' + /";+ '上传';xhr.open(POST", url);xhr.setRequestHeader('缓存控制', '无缓存');xhr.send(fd);}功能上传完成(事件){if (event.currentTarget.status === 200) {如果(开始<大小){开始 = 开始 + BYTES_PER_CHUNK;部分++;上传文件();}} 别的 {警报('错误');}}返回 (<div className="largeFileUploader"><form onSubmit={(事件)=>{event.preventDefault();fileGuid = uuid();发送请求();}}><div><输入类型=文件"多个={假}onChange={(事件)=>{setFile(event.target.files[0]);}}/>

<div><按钮类型=提交"disabled={!file}>上传</button>

</表单>

)}

.NET 5 控制器方法:

 [HttpPost][路线(上传")]公共异步任务上传(IFormCollection 表单数据){尝试{var part = int.Parse(formData[part"].ToString());var fileGuid = Guid.Parse(formData[fileGuid"].ToString());var rawFileName = formData[rawFileName"].ToString();string filePath = Path.Combine(_appConfig.DocumentFilesPath, fileGuid.ToString() + ." + rawFileName.Split(.").Last());使用 (Stream fileStream = new FileStream(filePath, part == 0 ? FileMode.Create : FileMode.Append)){等待 formData.Files.First().CopyToAsync(fileStream);fileStream.Close();}返回确定();}捕获(异常异常){}返回状态代码(500);}

I have a .net 5 API which has an endpoint that accepts a model consisting of an IFormFile File, string Description and string Name.

When Posting a form using axios from my react client everything works just fine using a 55.500kb file however when posting a file of 250,000kb the request appears to leave the client without any issue but the entire request is null when the endpoint is hit.

My API endpoint is decorated with RequestSizeLimit of 2147483648 and is mirrored in the web.config.

I'm guessing the reason is that the file being posted is too large but not 100% sure on this. If this is the reason do I need to somehow stream or chunk the request or is something else the root cause of this issue?

React function to post form:

    handleSubmit = async () => {
        this.setState({ componentState: LOADING }, async () => {
            let form = new FormData();
            form.append("title", this.state.title);
            form.append("reference", this.state.reference);
            form.append("description", this.state.description);
            form.append("price", this.state.price);
            form.append("scormFile", this.state.file);

            let response = await uploadCourseAsync(form);
            
            if (response.isSuccessStatusCode) {
                this.setState({ componentState: SUCCESS });
            }
            else {
                this.setState({ errors: response.errors })
            }
        })
    }

.net endpoint to receive request:

        [RequestSizeLimit(2147483648)]
        [HttpPost("UploadCourse")]
        public async Task<IActionResult> UploadCourse([FromForm] CreateCourseCommand command)
        {
            var ms = new MemoryStream();
            await command.ScormFile.CopyToAsync(ms);
            var byteArrayContent = new ByteArrayContent(ms.ToArray());
            var multipartContent = new MultipartFormDataContent
            {
                {byteArrayContent, command.ScormFile.Name, command.ScormFile.FileName},
                {new StringContent(command.Description), "Description"},
                {new StringContent(command.Reference), "Reference"},
                {new StringContent(command.Price), "Price"},
                {new StringContent(command.Title), "Title"},
                {new StringContent(User.Claims.FirstOrDefault(c => c.Type == "Id")?.Value ?? string.Empty), "UploadedById"},
                {byteArrayContent, command.ScormFile.Name, command.ScormFile.FileName}
            };

            var url = _serviceUrlConfig.CourseService + "/course/uploadcourse";
            var myHttpClient = new HttpClient();
            var response = await myHttpClient.PostAsync(url, multipartContent);
            return Ok(response);
        }

Any advice would be great, thanks in advance.

解决方案

POST message max. size is usually limited by http servers to 2 GB. This code allows you to download files of any size.

React component:

import React, { useState } from 'react';
import { v4 as uuid } from 'uuid';

export default function LargeFileUploader(props) {
    const BYTES_PER_CHUNK = 10485760; // 10MB chunk sizes.
    var start;
    var part;
    var SIZE = 0;
    var xhr;
    var fileGuid = '';
    const [file, setFile] = useState('');

    function sendRequest() {
        SIZE = file.size;
        start = 0;
        part = 0;
        xhr = new XMLHttpRequest();
        xhr.addEventListener("load", uploadComplete, false);
        uploadFile(part);
    }
    function uploadFile() {
        var blobFile = file.slice(start, BYTES_PER_CHUNK + start);
        var fd = new FormData();
        fd.append("file", blobFile);
        fd.append("fileguid", fileGuid);
        fd.append('part', part);
        fd.append('rawFileName', file.name);
        fd.append('partsTotal', Math.ceil(SIZE / BYTES_PER_CHUNK));

        var url = process.env.PUBLIC_URL + "/" + 'Files' + "/" + 'Upload';
        xhr.open("POST", url);
        xhr.setRequestHeader('Cache-Control', 'no-cache');
        xhr.send(fd);
    }

    function uploadComplete(event) {
        if (event.currentTarget.status === 200) {
            if (start < SIZE) {
                start = start + BYTES_PER_CHUNK;
                part++;
                uploadFile();
            }
        } else {
            alert('error');
        }
    }

    return (
        <div className="largeFileUploader">
            <form onSubmit={(event) => {
                event.preventDefault();
                fileGuid = uuid();
                sendRequest();
            }}>                
                <div>
                    <input type="file" multiple={false}
                        onChange={(event) => {
                            setFile(event.target.files[0]);
                        }}
                    />
                </div>
                <div>
                        <button type="submit" disabled={!file}>Upload</button>
                </div>
            </form>
        </div>
    )
}

.NET 5 Controller method:

    [HttpPost]        
    [Route("Upload")]
    public async Task<IActionResult> Upload(IFormCollection formData)
    {
        try
        {
            var part = int.Parse(formData["part"].ToString());
            var fileGuid = Guid.Parse(formData["fileGuid"].ToString());
            var rawFileName = formData["rawFileName"].ToString();
            string filePath = Path.Combine(_appConfig.DocumentFilesPath, fileGuid.ToString() + "." + rawFileName.Split(".").Last());

            using (Stream fileStream = new FileStream(filePath, part == 0 ? FileMode.Create : FileMode.Append))
            {
                await formData.Files.First().CopyToAsync(fileStream);
                fileStream.Close();
            }

            return Ok();
        }
        catch (Exception exception)
        {
        }

        return StatusCode(500);
    }

这篇关于发布大文件 React.js &amp;.net 5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
C#/.NET最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆