是否可以使用可用于模型绑定的非公共无参数构造函数?

时间:2017-05-30 12:09:54

标签: c# asp.net model-view-controller model-binding

我有一个PCOO课程。我不希望无参数构造函数公开。

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)
{
}

是否可以拥有非公开构造函数,或者是绝对需要的公共构造函数?

2 个答案:

答案 0 :(得分:4)

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

您必须覆盖默认的模型绑定器并创建自己的模型绑定器。如果这是值得的,那么时间取决于你。

采取的步骤:

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

Read more on custom bindings here.

答案 1 :(得分:0)

此外,虽然帕特里克的答案很棒并且展示了如何做到这一点(在这种努力真正有意义的情况下),我只是在另一个SO post中添加了我注意到的东西。

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