In our codebase DTOs are immutable types with readonly fields, getters for the state and a constructor that accepts the values, so a hypothetical person type looks like this:
public class Person
{
private readonly String _firstName;
private readonly String _secondName;
public Person(String firstName, String secondName)
{
_firstName = firstName;
_secondName = secondName;
}
public String FirstName
{
get { return _firstName; }
}
public String SecondName
{
get { return _secondName; }
}
}
With Web API, is it possible to bind a model like this without exposing public setters on the properties?
YES, IT IS POSSIBLE to bind this without public properties. By default, you would need a public setter for this to work. However, if you have a constructor that does the initializing and it is the default one, the framework can construct the objects.
In the example that you have shown, since there is only one constructor which accepts both fields (FirstName and LastName), it uses the default constructor to create the object.
This works because of the de-serialization capabilities of the Json serializer. If you have multiple constructors you can use the JsonConstructor attribute to specify which constructor to use and that can set your readonly fields.
You could deal with this by having a model that you bind your WebAPI request to, with an implicit conversion to the immutable type:
public class PersonRequestModel
{
public String FirstName { get; set; }
public String SecondName { get; set; }
public static implicit operator Person(PersonRequestModel request) {
return new Person(request.FirstName, request.SecondName);
}
}
public class Person
{
private readonly String _firstName;
private readonly String _secondName;
public Person(String firstName, String secondName)
{
_firstName = firstName;
_secondName = secondName;
}
public String FirstName
{
get { return _firstName; }
}
public String SecondName
{
get { return _secondName; }
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With