Dealing with C# records in ASP.NET Core model binding
source link: https://alexanderzeitler.com/articles/dealing-with-csharp-records-in-aspnet-core-model-binding/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Dealing with C# records in ASP.NET Core model binding
Photo by Viktor Forgacs on Unsplash
C# records are a great addition to the language. They are immutable, have value semantics, and are great for modeling data. But when it comes to model binding in ASP.NET Core, things are getting a bit more complicated. Let's see how we can deal with C# records in ASP.NET Core model binding.
What are C# records?
C# records are a new feature in C# 9. They are a reference type, but they have value semantics. This means that they are immutable and can be compared by value. They are great for modeling data, and they are a great addition to the language.
Here is an example of a C# record:
public record Person(string FirstName, string LastName);
In this example, we have a Person
record with two properties: FirstName
and LastName
.
Model binding in ASP.NET Core
Model binding is the process of mapping data from an HTTP request to an object in your application. It is a fundamental part of building web applications, and it is used to handle form submissions, query string parameters, and other types of data.
In ASP.NET Core, model binding is done automatically by the framework. When you create a controller action that takes a parameter, the framework will try to bind data from the request to that parameter.
Here is an example of a controller action that takes a Person
parameter:
[HttpPost]
public IActionResult CreatePerson(Person person)
{
// ...
}
In this example, the framework will try to bind data from the request to a Person
object. This is done automatically by the framework, and it is a very powerful feature.
Dealing with C# records in ASP.NET Core model binding
At a first glance, everything seems to be easy with C# records. But when it comes to model binding in ASP.NET Core, things are getting a bit more complicated.
Now there are two issues with C# records and model binding in ASP.NET Core:
- The model binding needs a parameterless constructor
- If you want to translate property names or set display error messages, you need to use the
Display
andRequired
attributes.
The shortest way (I know) to have a parameterless constructor while maintaining the positional constructor is this one - I want to avoid embrace a class
like style:
public record Person(
string? FirstName,
string? LastName
)
{
public InviteUser() : this(
null,
null,
)
{
}
}
The Display
and Required
attributes are used to set display error messages and translate property names. Here is an naive approach to use them:
public record Person(
[Display(Name = "First Name")]
[Required(ErrorMessage = "The first name is required")]
string? FirstName,
[Display(Name = "Last Name")]
[Required(ErrorMessage = "The last name is required")]
string? LastName
)
{
public InviteUser() : this(
null,
null
)
{
}
}
This won't work, because the Display
and Required
attributes are not recognized by the model binding. You need to do it that way:
public record Person(
[property:Display(Name = "First Name")]
[property:Required(ErrorMessage = "The first name is required")]
string? FirstName,
[property:Display(Name = "Last Name")]
[property:Required(ErrorMessage = "The last name is required")]
string? LastName
)
{
public InviteUser() : this(
null,
null
)
{
}
}
The reason for this is, without the property:
prefix, the attributes are not recognized by the model binding because FirstName
and LastName
are not properties of the Person
but constructor parameters. By adding the property:
prefix, the attributes are emitted for generated properties instead and the model binding can recognize them.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK