无法从抽象 class 创建继承 class 的实例

Can not create instance of an inherited class from an abstract class

我有一个 class 继承自 abstarct class。在剃须刀上,当我创建子 class 的实例时,出现如图所示的错误:

Cannot create an abstract class

但是 StuffRegisterSearchParameterVM 不是抽象的 class。为什么会这样?

控制器

public ActionResult SearchRegistration(SearchParameterVM model)

型号

abstract public class SearchParameterVM
{
    public string FromDate { get; set; }
    public string ToDate { get; set; }
    public int? MainTestRegisterId { get; set; }
    public int TestTypeId { get; set; }
    public bool IsForAnsweringPage { get; set; }

}


public class StuffRegisterSearchParameterVM : SearchParameterVM
{
    public int? StuffId { get; set; }
    public string Code { get; set; }
}

你不能使用抽象 class 作为动作的参数,因为 asp.net mvc 不知道任何关于发布对象类型的信息,它试图创建一个参数类型,而这个类型是抽象的. 因此,将其替换为具体 class 或创建 special binder.

定义动作时:

public ActionResult SearchRegistration(SearchParameterVM model)

这定义了一个方法,当向服务器发出 http 请求时,MVC 将根据您的路由调用该方法。该 http 请求可能仅包含参数,就像您拥有 Web 表单一样。 MVC model binding 只是创建在参数中指定的 class 实例到 C# 中的操作,并尝试根据 http 调用中传递的 http 参数设置 属性 值。此调用可能来自您所拥有的视图操作、来自静态 html 页面、来自程序或您可以进行 http 调用的任何其他地方。当它是一个抽象 class 时,它无法创建一个 it.If 的实例,你有 3 个子 classes 基于你的抽象 class,MVC 无法分辨哪个输入要创建的内容。

您可以查看 this question 了解更多信息。

那么,如果只给定具有不同值的参数名称,那么当调用该操作时,您如何确定内存中应该存在哪些具体 class?您可以创建在其参数中具有不同类型的不同路由和操作。您还可以检查这些参数并根据传递的参数创建不同的具体 classes。例如,如果您想根据是否传递了 'code' 值来使用某个 class,您要么必须 create your own IModelBinder 来确定哪个具体 class 基于传递的查询参数:

public class MyModelBinder : IModelBinder {
  public object BindModel(ControllerContext controllerContext,     
                          ModelBindingContext bindingContext) {
    // create different concrete instance based on parameters
    ValueProviderResult code = bindingContext.ValueProvider.GetValue("Code");
    if (code.AttemptedValue != null) {
      // code is passed as a parameter, might be our class
      // create instance of StuffRegisterSearchParameterVM  and return it
    }

    // no Code parameter passed, check for others
  }
}

然后你必须在你的启动中告诉你你有一个特殊的模型活页夹 对于你的摘要 class:

ModelBinders.Binders.Add(typeof(SearchParameterVM), new MyModelBinder());

或者您可以在操作中做一些事情来确定要创建的类型并使用 TryUpdateModel 来设置值:

public ActionResult SearchRegistration() {
  SearchParameterVM model = null;
  if (Request.Parameters["code"] != null) {
    model = new StuffRegisterSearchParameterVM();
    TryUpdateModel(model); // check return value
  }
}