chanalva 2023-07-21 14:47 采纳率: 0%
浏览 9

控制器如何获取Content-Type 为multipart/form-data时 Boundary中的附加参数

Asp.Net Core 在大文件的上传下载中,官方文档给的方案是设置 Content-Type 为 multipart/form-data,以下下为客户端发送上传的请求

string Boundary = new Guid().ToString().Replace("-", "");

MultipartFormDataContent content = new MultipartFormDataContent(Boundary);

content.Headers.ContentType = MediaTypeHeaderValue.Parse( $"multipart/form-data; boundary={Boundary}" );

//传入文件
var fileContent = System.IO.File.ReadAllBytesAsync( fullPath ).Result;
var byteArrayContent = new ByteArrayContent(fileContent);
content.Add( byteArrayContent, "file", "123.txt" );

//传入token(字符串格式)
string token = "12312";
System.Net.Http.StringContent stringContent = new(token);
content.Add( stringContent, "token" );

content.Add( new StringContent( "num1" ), "num1" );//参数一
content.Add( new StringContent( "num2" ), "num1" );//参数二            

//发送请求 
var postResponse = client.PostAsync(reqUrl, content).Result;

//获取请求结果
string res = postResponse.Content.ReadAsStringAsync( ).Result;

但在官方示例中只给出了怎样将上述的文件流保存成文件,但是没有提供如果获取附加参数 如上述num1 和 num2 的方法,在网络上找了很多资料都为找到服务端控制器获取的方法,请问需如何获取?下面为服务端控制器代码:

/// <summary>
        /// Action for upload large file
        /// </summary>
        /// <remarks>
        /// Request to this action will not trigger any model binding or model validation,
        /// because this is a no-argument action
        /// </remarks>
        /// <returns></returns>
        [DisableRequestSizeLimit]
        [HttpPost]
        [Route( nameof( UploadLargeFile ) )]
        public async Task<IActionResult> UploadLargeFile( )
        {
            //MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent();
            var request = HttpContext.Request;
            

            // validation of Content-Type
            // 1. first, it must be a form-data request
            // 2. a boundary should be found in the Content-Type

            Boolean  bb = false;
            
            Microsoft.Net.Http.Headers.MediaTypeHeaderValue mediaTypeHeader = null;


            try
            {
                MediaTypeHeaderValue.TryParse( request.ContentType, out mediaTypeHeader );
                bb = true;
            }
            catch ( Exception ex )
            { 
                Console.WriteLine( ex.Message );
            }


            if ( !request.HasFormContentType ||
                // !MediaTypeHeaderValue.TryParse( request.ContentType, out var mediaTypeHeader ) ||
                !bb||
                string.IsNullOrEmpty( mediaTypeHeader.Boundary.Value ) )
            {
                return new UnsupportedMediaTypeResult( );
            }

            

        //    var boundary = MultipartRequestHelper.GetBoundary(
        //MediaTypeHeaderValue.Parse(Request.ContentType),
        //_defaultFormOptions.MultipartBoundaryLengthLimit);

            try
            {

                var reader = new MultipartReader(mediaTypeHeader.Boundary.Value, request.Body);
                var section = await reader.ReadNextSectionAsync();

                var boundary = GetBoundary( MediaTypeHeaderValue.Parse( request.ContentType), int.MaxValue);

                // This sample try to get the first file from request and save it
                // Make changes according to your needs in actual use
                while ( section != null )
                {

                    var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition,
                    out var contentDisposition);



                    if ( hasContentDispositionHeader && contentDisposition.DispositionType.Equals( "form-data" ) &&
                        !string.IsNullOrEmpty( contentDisposition.FileName.Value ) )
                    {
                        // Don't trust any file name, file extension, and file data from the request unless you trust them completely
                        // Otherwise, it is very likely to cause problems such as virus uploading, disk filling, etc
                        // In short, it is necessary to restrict and verify the upload
                        // Here, we just use the temporary folder and a random file name

                        // Get the temporary folder, and combine a random file name with it
                        var fileName = Path.GetRandomFileName();
                        var saveToPath = Path.Combine(Path.GetTempPath(), fileName);

                        using ( var targetStream = System.IO.File.Create( saveToPath ) )
                        {
                            await section.Body.CopyToAsync( targetStream );
                        }

                        return Ok( );
                    }

                    section = await reader.ReadNextSectionAsync( );
                }
            }
            catch ( Exception ex )
            {
                Console.WriteLine( ex.Message );
            }

            // If the code runs to this location, it means that no files have been saved
            return BadRequest( "No files data in the request." );
        }

  • 写回答

1条回答 默认 最新

  • _东_ 2023-07-24 15:01
    关注

    看上去你是通过表单提交的请求?如果是这样的话,你可以尝试把文件和这些参数都封装到一个Model中,然后再发送请求,使用[FromForm]属性。简单参考这个相似问题:

    评论

报告相同问题?

问题事件

  • 创建了问题 7月21日

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效