How to bind a multipart/form-data file without filename to IFormFile in ASP.NET Core

让人想犯罪 __ 提交于 2021-02-07 10:11:39

问题


In a simple controller action in ASP.NET Core 3.1 that accepts multipart/form-data parameters:

using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace WebApplication
{
    public class Controller : ControllerBase
    {
        [HttpPost("length")]
        public IActionResult Post([FromForm] Input input)
        {
            if (!ModelState.IsValid)
                return new BadRequestObjectResult(ModelState);

            return Ok(input.File.Length);
        }

        public class Input
        {
            [Required]
            public IFormFile File { get; set; }
        }
    }
}

When I send a multipart/form-data with a File with no filename (which is acceptable under RFC 7578) it is not recognized as an IFormFile. For example:

using System;
using System.IO;
using System.Threading.Tasks;
using System.Net.Http;

namespace ConsoleApp4
{
    class Program
    {
        static async Task Main(string[] args)
        {
            await Test(withFilename: true);
            await Test(withFilename: false);
        }

        static async Task Test(bool withFilename)
        {
            HttpClient client = new HttpClient();

            var fileContent = new StreamContent(new FileStream("/Users/cucho/Desktop/36KB.pdf", FileMode.Open, FileAccess.Read));

            var message = new HttpRequestMessage(
                HttpMethod.Post,
                "http://localhost:5000/length"
            );

            var content = new MultipartFormDataContent();

            if (withFilename)
            {
                content.Add(fileContent, "File", "36KB.pdf");
            }
            else
            {
                content.Add(fileContent, "File");
            }

            message.Content = content;

            var response1 = await client.SendAsync(message);

            var withString = withFilename ? "With" : "Without";

            Console.WriteLine($"{withString} filename: {(int)response1.StatusCode}");
        }
    }
}

results in:

With filename: 200
Without filename: 400

How can I bind that File without filename to the IFormFile object?

Edit:

I found in the ContentDispositionHeaderValueIdentityExtensions the following method:

public static class ContentDispositionHeaderValueIdentityExtensions
{
    /// <summary>
    /// Checks if the content disposition header is a file disposition
    /// </summary>
    /// <param name="header">The header to check</param>
    /// <returns>True if the header is file disposition, false otherwise</returns>
    public static bool IsFileDisposition(this ContentDispositionHeaderValue header)
    {
        if (header == null)
        {
            throw new ArgumentNullException(nameof(header));
        }

        return header.DispositionType.Equals("form-data")
            && (!StringSegment.IsNullOrEmpty(header.FileName) || !StringSegment.IsNullOrEmpty(header.FileNameStar));
    }

And a similar code in FormFeature, which I think is how it decides whether the part is a file or not.

来源:https://stackoverflow.com/questions/60157395/how-to-bind-a-multipart-form-data-file-without-filename-to-iformfile-in-asp-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!