基本实体的ASP.NET MVC通用控制器

时间:2016-12-22 11:38:58

标签: c# asp.net-mvc inheritance controller

我试图创建一个通用控制器来处理将从基类继承的实体。

目前,我有一个"部门"控制器:

public class DepartmentsController : BaseController
{
    Departments model;

    public virtual ActionResult Index()
    {                        
        model = new Departments("");
        return View("Index", model.SearchAsList());
    }

    [HttpPost]
    public virtual ActionResult Insert(Departments obj)
    {
        obj.Create();
        return RedirectToAction("Index");
    }

    [HttpPost]
    public virtual ActionResult Update(Departments obj)
    {
        obj.Update();
        return RedirectToAction("Index");
    }

    public virtual ActionResult Edit(int id)
    {
        model = new Departments("");
        model.ID = id;
        return View("Edit", model.SearchAsList()[0]);
    }

    public virtual ActionResult Details(int id)
    {
        model = new Departments("");
        model.ID = id;
        return View("Details", model.SearchAsList()[0]);
    }

    public virtual ActionResult Delete(int id)
    {
        model = new Departments("");
        model.ID = id;
        model.Delete();
        return RedirectToAction("Index");
    }

}

基础控制器:

public class BaseController : Controller
{
    public virtual ActionResult Create()
    {
        return View("Create");
    }

}

以及实体和基础实体:

public class BaseEntity
{
    public int Create { get; set; }
}

public class Department : BaseEntity
{
    public int MySpecificMethod { get; set; }
}

但我想让它更通用,以便部门控制器(以及我所有其他实体控制器不必有任何操作,除非它们与基本控制器中的操作不同。"创建" action是唯一没有引用" Department"所以我已经将它添加到Base Controller但我不确定如何修改它以便它将接受任何对象类型基于我的基础实体。

我已经看过你可以通过一个例子的例子。

 public class DepartmentsController<T> : BaseController
        where T: class

然而,&#34; T&#34;在我的实例中将是一个我知道继承自&#34; BaseEntity&#34;因此,我希望能够访问它的公共职能。

我将这个例子改为:

public class DepartmentsController<T> : BaseController
        where T: BaseEntity

现在&#34; T&#34;有权访问基本实体函数(例如Create),但这给我提供了如何从实际的Department类(例如MySpecificMethod)访问特定函数的问题。

希望这是有道理的,有人可以解释我如何修改我的控制器和基本控制器。

谢谢!

1 个答案:

答案 0 :(得分:0)

为此,您需要能够在绑定步骤中选择一个派生类(即通过发送到服务器的参数)。

接下来,您需要一个自定义的ModelBinder,重写方法

protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)

然后,您将能够创建所需的派生类的实例...

就我而言,我有:

public class AbstractC1 { . . . }
public class DerivedC1 : AbstractC1   { . . . }
public class DerivedC2 : AbstractC2   { . . . }

然后,在我的控制器中:

public ActionResult MyAction([ModelBinder(typeof(CustomModelBinder))] AbstractC1 myData) { . . . }

而且,在我的ModelBinder中:

public class CustomModelBinder : DefaultModelBinder {
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) {
    AbstractC1 data = MyFactory.createDerivedClass(...);
    return data;
}

MyFactory创建DerivedC1或DerivedC2的位置,具体取决于请求的某些参数。

但是......这允许你对所有派生类型使用一种通用方法,尽管你必须将它们用作基类,或者找到一种方法将它们转换为派生类。