Home > Software design >  ASP.NET Core MVC - Model Binding does not work for POST Request when Number Properties are Declared
ASP.NET Core MVC - Model Binding does not work for POST Request when Number Properties are Declared

Time:04-05

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 );

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

For older versions, the application/x-www-form-urlencoded approach is probably the most straightforward.

  • Related