ASP.NET 核心 MVC - 模型绑定不适用于 POST 客户端将数字属性声明为字符串时的请求

ASP.NET Core MVC - Model Binding does not work for POST Request when Number Properties are Declared as Strings Client-Side

我在 ASP.NET 核心中有一个控制器路由,它接受 application/json 数据。我打算将客户端的一些表单数据转换为 JSON,如下所示:

let formElement = document.getElementById("form-data");
let formData = new FormData(formElement);
let formJson = Object.fromEntries(formData.entries());

console.log("submitting:", formJson)

let response = await request("/mycontroller/addnew", "POST", formJson);

与服务端路由如下:

[HttpPost]
public IActionResult AddNew([FromBody] MyFormData formData )
{
    // Do Stuff
}

public class MyFormData 
{
    public int Id { get; set; }
    public string Message { get; set; }
}

使用上面的示例设置,如果我提交:

,我可以让 MyFormData 模型正确绑定
{
    "id": 123,
    "message": "testing testing"
}

但是,当我提交以下内容时,formData 为空:

{
    "id": "123",
    "message": "testing testing"
}

鉴于您不能在 HTML 形式中指定数据类型,将我的所有属性显式转换为正确的类型会很痛苦。下面的文档还暗示服务器应该能够处理默认情况下表示为字符串的数字:

https://andrewlock.net/model-binding-json-posts-in-asp-net-core/ https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-6.0

我是否遗漏了任何明显的信息或者这是预期的行为?

看起来模型绑定的行为与您预期的不一样。 这可以在启动时配置:

services.AddMvc().AddJsonOptions(o =>
{o.JsonSerializerOptions.PropertyNamingPolicy = null;
o.JsonSerializerOptions.DictionaryKeyPolicy = null; });

另外,我在我的项目中解决了这个问题,在客户端的 post 请求中使用 application/x-www-form-urlencoded 作为 content-type。如果您使用此方法,您可能需要删除 [frombody] 标签。

从 .NET Core 5 开始,您似乎可以按如下方式配置数字处理:

services
    .AddControllersWithViews()
    .AddJsonOptions(o => o.JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString );

https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions.numberhandling?view=net-6.0&viewFallbackFrom=netcore-3.1#system-text-json-jsonserializeroptions-numberhandling

对于旧版本,application/x-www-form-urlencoded 方法可能是最直接的。