I have a controller route in ASP.NET Core that accepts application/json data. I was intending to convert some form data on the client-side into JSON as follows:
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);
With the server-side route as follows:
[HttpPost]
public IActionResult AddNew([FromBody] MyFormData formData )
{
// Do Stuff
}
public class MyFormData
{
public int Id { get; set; }
public string Message { get; set; }
}
With the example setup above, I can get the MyFormData
model to bind correctly if I submit:
{
"id": 123,
"message": "testing testing"
}
However, when I submit the following, formData is null:
{
"id": "123",
"message": "testing testing"
}
Given that you cannot specify data types in the HTML form, it'd be a pain to explicitly cast all my properties to their correct types. The documentation below also implies that the server should be able to handle numbers expressed as strings by default:
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
Am I missing anything obvious here or is this expected behaviour?
CodePudding user response:
It looks like the modelbinding is not behaving as you expect it. This can be configured in the startup with:
services.AddMvc().AddJsonOptions(o =>
{o.JsonSerializerOptions.PropertyNamingPolicy = null;
o.JsonSerializerOptions.DictionaryKeyPolicy = null; });
Also, I have solved this issue in my projects with using application/x-www-form-urlencoded
as content-type in the post requests in the clientside. You may need to remove the [frombody] tag if you're using this method.
CodePudding user response:
Starting from .NET Core 5, it looks as though you can configure number handling as follows:
services
.AddControllersWithViews()
.AddJsonOptions(o => o.JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString );
For older versions, the application/x-www-form-urlencoded
approach is probably the most straightforward.