是否可以有一个非 public 的无参数构造函数可用于模型绑定?

Is it possible to have a non-public parameterless constructor that can be used for model binding?

我有一个关注 POCO class。我不希望无参数构造函数是 public.

public class FileDownloadRequest
    {
       //public FileDownloadRequest() { }
        public FileDownloadRequest(int fileId, RepositoryFolderTypes fileType) //RepositoryFolderTypes is an enum, not a class
        {
            this.FileId = fileId;
            this.FileType = fileType;
        }
        public int FileId { get; set; }
        public RepositoryFolderTypes FileType { get; set; } //an enum
    }

当我尝试对以下控制器操作发出 https://10.27.8.6/Files/DownloadFile?fileId=1&folderType=SRC 请求时,我收到一条错误消息,指出此对象不存在无参数构造函数。

[HttpGet]
public async Task<HttpResponseMessage> DownloadFile([FromUri] FileDownloadRequest request)
{
}

是否可以使用非 public 的构造函数,或者 public 是绝对必需的?

是的,您可以使用任何您喜欢的构造函数,但您必须自己进行模型绑定。问题出在 DefaultModelBinder.CreateModel,它使用 parameterless public constructor.

您必须覆盖默认的模型活页夹并创建您自己的活页夹。如果值得,时间由您决定。

要采取的步骤:

  • 覆盖 CreateModel
  • 检查 modelType 一些通用约束,您需要使用参数调用构造函数的模型;
  • 用参数调用Activator.CreateInstance(Type, Object[])。您可以从 bindingContext;
  • 中获取它们的值
  • 通过 ModelBinder 属性或全局注册模型绑定器。

Read more on custom bindings here.

此外,虽然帕特里克的回答很好并且展示了如何去做(在这些努力确实有意义的情况下),但我只是添加了我在另一个 SO post.[=12] 中注意到的内容=]

基本上,将无参数构造函数标记为[Obsolete("Comment to indicate its for binding only")],这样可以防止其他人意外调用无参数构造函数。 (从而明确显示请求对象需要哪些属性)