我有一个继承自abstarct
类的类。在剃刀上,当我创建子类的实例时,我得到了这个错误,如图所示:
无法创建抽象类
但是StuffRegisterSearchParameterVM
不是抽象类。为什么会这样?
控制器
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; }
}
答案 0 :(得分:3)
你不能使用抽象类作为动作的参数,因为asp.net mvc不知道任何abount发布的对象类型,它试图创建一个参数类型,而这个类型是抽象的。 因此,将其替换为具体类或创建special binder。
答案 1 :(得分:1)
定义操作时:
public ActionResult SearchRegistration(SearchParameterVM model)
它定义了一个方法,当向服务器发出http请求时,MVC将根据您的路由调用该方法。该http请求可能只包含您拥有Web表单时的参数。 MVC model binding只是在C#中的操作的参数中创建一个类的实例,并尝试根据http调用中传递的http参数设置属性值。此调用可以来自您拥有的视图操作,静态html页面,程序或其他任何可以进行http调用的操作。当它是一个抽象类时,它不能创建它的实例。如果你有3个基于你的抽象类的子类,MVC将无法分辨出要创建的类型。
您可以查看this question以获取更多信息。
那么,如果只给出具有不同值的参数名称,那么在调用该操作时,如何确定内存中应该存在哪个具体类?您可以创建在参数中具有不同类型的不同路径和操作。您还可以检查这些参数,并根据传递的参数创建不同的具体类。例如,如果您想根据是否传递“代码”值来使用某个类,那么您将需要create your own IModelBinder
,这可以根据传递的查询参数确定哪个具体类:
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
}
}
然后你必须在你的创业公司告诉你有一个特殊的模型绑定器 为你的抽象类:
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
}
}