Web API 绑定不可变模型
Web API binding immutable models
在我们的代码库中,DTO 是具有只读字段的不可变类型、状态的 getter 和接受值的构造函数,因此假设的 person 类型如下所示:
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; }
}
}
使用 Web API,是否可以像这样绑定模型而不暴露属性上的 public 设置器?
是的,可以 在没有 public 属性的情况下绑定它。默认情况下,您需要 public setter 才能正常工作。但是,如果您有一个进行初始化的构造函数并且它是默认构造函数,则框架可以构造对象。
在您展示的示例中,由于只有一个构造函数接受两个字段(FirstName 和 LastName),因此它使用默认构造函数来创建对象。
这是因为 Json 序列化器的反序列化功能。如果您有多个构造函数,您可以使用 JsonConstructor 属性来指定要使用的构造函数以及可以设置只读字段的构造函数。
您可以通过将 WebAPI 请求绑定到一个模型并隐式转换为不可变类型来处理此问题:
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; }
}
}
在我们的代码库中,DTO 是具有只读字段的不可变类型、状态的 getter 和接受值的构造函数,因此假设的 person 类型如下所示:
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; }
}
}
使用 Web API,是否可以像这样绑定模型而不暴露属性上的 public 设置器?
是的,可以 在没有 public 属性的情况下绑定它。默认情况下,您需要 public setter 才能正常工作。但是,如果您有一个进行初始化的构造函数并且它是默认构造函数,则框架可以构造对象。
在您展示的示例中,由于只有一个构造函数接受两个字段(FirstName 和 LastName),因此它使用默认构造函数来创建对象。
这是因为 Json 序列化器的反序列化功能。如果您有多个构造函数,您可以使用 JsonConstructor 属性来指定要使用的构造函数以及可以设置只读字段的构造函数。
您可以通过将 WebAPI 请求绑定到一个模型并隐式转换为不可变类型来处理此问题:
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; }
}
}