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