问题
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