每个请求的MVC检索模型

时间:2008-09-16 00:26:57

标签: asp.net-mvc

假设我正在开发一个将由多个部门使用的帮助台应用程序。应用程序中的每个URL都包含一个指示特定部门的密钥。密钥始终是系统中每个操作的第一个参数。例如

http://helpdesk/HR/Members
http://helpdesk/HR/Members/PeterParker
http://helpdesk/HR/Categories
http://helpdesk/Finance/Members
http://helpdesk/Finance/Members/BruceWayne
http://helpdesk/Finance/Categories

问题是,在每个请求的每个操作中,我必须使用此参数,然后根据该密钥从存储库中检索Helpdesk部门模型。从该模型我可以检索成员列表,类别等,这对于每个帮助台部门是不同的。这显然违反了DRY。

我的问题是,如何创建一个基本控制器,它为我这样做,以便URL中指定的特定帮助台部门可用于所有派生控制器,我可以专注于操作?

3 个答案:

答案 0 :(得分:2)

我的一个项目中有类似的场景,我倾向于使用ModelBinder而不是使用单独的继承层次结构。您可以创建一个ModelBinder属性来从RouteData获取实体/ entites:

public class HelpdeskDepartmentBinder : CustomModelBinderAttribute, IModelBinder {

    public override IModelBinder GetBinder() {
        return this;
    }

    public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState) {
        //... extract appropriate value from RouteData and fetch corresponding entity from database. 
    }
}

...然后您可以使用它来使HelpdeskDepartment适用于您的所有操作:

public class MyController : Controller {
    public ActionResult Index([HelpdeskDepartmentBinder] HelpdeskDepartment department) {
        return View();
    }
}

答案 1 :(得分:0)

免责声明:我目前正在运行MVC Preview 5,因此其中一些可能是新的。

最佳实践方法:只需实现一个静态实用程序类,该实用程序类提供执行模型查找的方法,将ActionData中的RouteData作为参数。然后,从需要该模型的所有操作中调用此方法。

kludgy方式,仅当每个控制器中的每个操作都需要模型时,并且您真的不希望在操作中有额外的方法调用:在Controller-implementation-base-class中,重写ExecuteCore (),使用RouteData填充模型,然后调用base.ExecuteCore()。

答案 2 :(得分:0)

您可以通过普通的C#继承创建基本控制器类:

public abstract class BaseController : Controller 
{
}

public class DerivedController : BaseController 
{
}

您只能将此基类用于需要部门的控制器。您不必执行任何特殊操作来实例化派生控制器。

从技术上讲,这很好用。然而,从设计的角度来看存在一些风险。如果,如你所说,你的所有控制器都需要一个部门,这很好。如果只有部分人需要部门,那可能还是可以的。但是,如果某些控制器需要一个部门,而其他控制器需要一些其他继承的行为,并且两个子集相交,那么您可能会发现自己陷入了多重继承问题。这表明继承不是解决您所述问题的最佳设计。