Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基本实体的ASP.NET MVC通用控制器_C#_Asp.net Mvc_Inheritance_Controller - Fatal编程技术网

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

C# 基本实体的ASP.NET MVC通用控制器,c#,asp.net-mvc,inheritance,controller,C#,Asp.net Mvc,Inheritance,Controller,我正在尝试创建一个通用控制器,它可以处理所有从基类继承的实体 目前,我有一个“部门”控制员: public class DepartmentsController : BaseController { Departments model; public virtual ActionResult Index() { model = new Departments(""); return Vie

我正在尝试创建一个通用控制器,它可以处理所有从基类继承的实体

目前,我有一个“部门”控制员:

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 ActionResult MyAction([ModelBinder(typeof(CustomModelBinder))] AbstractC1 myData) { . . . }
基本控制器:

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 ActionResult MyAction([ModelBinder(typeof(CustomModelBinder))] AbstractC1 myData) { . . . }
以及实体和基础实体:

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

public class Department : BaseEntity
{
    public int MySpecificMethod { get; set; }
}
但是我想让它更通用,这样部门控制器(以及我的所有其他实体控制器)就不必有任何动作,除非它们与基本控制器中的动作不同。“创建”动作是唯一不引用“部门”的动作因此,我已将其添加到基本控制器中,但我不确定如何修改它,以便它接受基于我的基本实体的任何对象类型

我见过一些例子,你可以通过一门课,例如

 public class DepartmentsController<T> : BaseController
        where T: class
公共类部门控制器:BaseController
T:在哪里上课
然而,我的实例中的“T”将是一个从“BaseEntity”继承的类,因此我希望能够访问它的公共函数

我将该示例更改为:

public class DepartmentsController<T> : BaseController
        where T: BaseEntity
公共类部门控制器:BaseController
其中T:BaseEntity
现在“T”确实可以访问基本实体函数(例如Create),但这给了我如何从实际的Department类(例如MySpecificMethod)访问特定函数的问题

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


谢谢!

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

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

protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
然后,您将能够创建所需派生类的实例

就我而言,我有:

public class AbstractC1 { . . . }
public class DerivedC1 : AbstractC1   { . . . }
public class DerivedC2 : AbstractC2   { . . . }
然后,在我的控制器中:

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 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


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

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

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

protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
然后,您将能够创建所需派生类的实例

就我而言,我有:

public class AbstractC1 { . . . }
public class DerivedC1 : AbstractC1   { . . . }
public class DerivedC2 : AbstractC2   { . . . }
然后,在我的控制器中:

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 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


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

因为
DefaultModelBinder
将无法绑定到
Department
(仅
BaseEntity
)当您提交时,每个视图对于每个继承类型都是不同的(使用适当的
@model xxx
声明),这种方法真的没有意义。为什么您的所有操作都是虚拟的?是否要覆盖它们?是的,我的模型视图当然会引用“部门”模型而不是基本实体,但是如果我创建一个新的“地址”实体,该实体的控制器将与我上面发布的“部门”控制器完全相同,但“部门”更改为“地址”。这对我来说意味着可以进行重构以提高效率,并将所有操作移到基类控制器中。然而,如何做到这一点是我一直在努力解决的问题!@Alex我想这只是我测试的遗留问题。但理论上是的,我希望将它们移到基类中,如果需要,可以选择重写它们与标准不同。由于提交时,
DefaultModelBinder
将无法绑定到
部门(仅
BaseEntity
),并且每个继承类型的每个视图都将不同(使用适当的
@model xxx
声明),这种方法真的没有意义。为什么所有操作都是虚拟的?是否要覆盖它们?是的,我的模型视图当然会引用“部门”模型,而不是基本实体,但是如果我创建一个新的“地址”实体,该实体的控制器将与“部门”完全相同我在上面贴了控制器,但“部门”改为“地址”。这对我来说意味着可以进行重构以提高效率,并将所有操作移到基类控制器中。然而,如何做到这一点是我一直在努力解决的问题!@Alex我想这只是我测试的遗留问题。但理论上是的,我希望将它们移到基类中,如果需要,可以选择重写它们这与标准不同。