为什么此字符串未绑定到 ASP.NET.Core API 操作中的文件名参数?

Why does this string not get bound to a filename parameter in ASP.NET .Core API Action?

我正在使用以下 header 和 body 以及在 http://localhost:50063/api/image:

上发布的 fiddler 测试 API
User-Agent: Fiddler
Content-Type: application/json; charset=utf-8
Host: localhost:50063
Content-Length: 32330

{"filename": "bot.png", "file": "base64 image ellided for brevity"}

示例代码来自 tutorial

[ApiController]
[Produces("application/json")]
[Route("api/Image")]
public class ImageController : Controller
{

    // POST: api/image
    [HttpPost]
    public void Post(byte[] file, string filename)
    {
        string filePath = Path.Combine(_env.ContentRootPath, "wwwroot/images/upload", filename);
        if (System.IO.File.Exists(filePath)) return;
        System.IO.File.WriteAllBytes(filePath, file);
    }

    //...

}

首先我收到错误 500,文件名为空。我向控制器 class 添加了 [ApiController] 属性,但出现错误 400 filename invalid.

当我在这里提出相同的请求时,filename 绑定到复合体 class:

    [HttpPost("Profile")]
    public void SaveProfile(ProfileViewModel model)
    {
        string filePath = Path.Combine(_env.ContentRootPath, "wwwroot/images/upload", model.FileName);
        if (System.IO.File.Exists(model.FileName)) return;
        System.IO.File.WriteAllBytes(filePath, model.File);
    }

    public class ProfileViewModel
    {
        public byte[] File { get; set; }
        public string FileName { get; set; }
    }

为什么会这样?

请求内容只能从body读取一次。

在第一个示例中,填充数组后它可以填充字符串,因为 body 已被读取。

在第二个示例中,它在 body 的一次读取中填充模型。

Once the request stream is read for a parameter, it's generally not possible to read the request stream again for binding other parameters.

参考Model Binding in ASP.NET Core