什么是ASP.NET MVC中基本控制器类的优秀候选者?

时间:2011-05-25 03:25:48

标签: asp.net-mvc controller base-class

我见过很多人谈论在他们的ASP.NET MVC项目中使用基本控制器。我见过的典型例子就是记录或者CRUD脚手架。基本控制器类的其他一些好用途是什么?

9 个答案:

答案 0 :(得分:37)

基本控制器类没有很好的用途。

现在听我说。

Asp.Net MVC,特别是MVC 3有大量的可扩展性钩子,它们为所有控制器添加功能提供了更加分离的方式。由于您的控制器类非常重要且对应用程序至关重要,因此保持它们的轻量级,敏捷性以及与其他所有内容松散耦合非常重要。

  • 记录基础设施属于 构造函数,应该注入 通过DI框架。

  • CRUD脚手架应该由 代码生成或自定义 ModelMetadata提供程序。

  • 全局异常处理应该是 由自定义ActionInvoker处理。

  • 全局视图数据和授权 应该由动作过滤器处理。 使用全局动作过滤器更容易 在MVC3中。

  • 常量可以放在另一个名为ApplicationConstants的类/文件中。

基本控制器通常由没有经验的MVC开发人员使用,他们不了解MVC的所有不同扩展性部分。现在不要误解我的意思,我不会因为所有错误的原因而与使用它们的人一起评判和合作。它的经验为您提供了解决常见问题的更多工具。

我几乎是肯定的,没有一个问题你用另一个扩展性钩子而不是基本控制器类来解决。除非存在显着的生产力原因并且您没有违反Liskov,否则不要采用最严格的耦合形式(继承)。我更愿意接受<在我的控制器(如public ILogger Logger { get; set; })上输入属性20秒,而不是引入紧密耦合,从而以更重要的方式影响应用程序。

即使像userId或多租户密钥这样的东西也可以放在ControllerFactory而不是基本控制器中。基本控制器类的耦合成本是不值得的。

答案 1 :(得分:8)

我喜欢使用基本控制器进行授权。

我没有使用“Authorize”属性来装饰每个动作,而是在基本控制器中进行授权。从数据库中为登录用户提取授权操作列表。

请阅读以下链接,了解有关授权的更多信息。 Good practice to do common authorization in a custom controller factory?

答案 2 :(得分:3)

我用它来访问会话,应用程序数据等。

我还有一个应用程序对象,它包含应用程序名称等内容,我可以从基类访问

基本上我将它用于我重复的事情

哦,我应该提一下,我不会将它用于商业逻辑或数据库访问。对于基类来说,常量也是一个不错的选择。我猜。

答案 3 :(得分:3)

我在很多项目中都使用过基本控制器而且效果很好。我主要用于

  • 异常记录
  • 通知(成功,错误,添加..)
  • 调用HTTP404错误处理

答案 4 :(得分:2)

根据我的经验,您希望放入基本控制器的大多数逻辑理想情况下都会进入动作过滤器。 Action Filter只能用常量初始化,因此在某些情况下你不能这样做。在某些情况下,您需要将操作应用于系统中的每个操作方法,在这种情况下,将逻辑放在基础中可能更有意义,而不是使用新的actionFilter属性注释每个操作方法。

我还发现将引用服务的属性(以其他方式与控制器分离)放入基础有助于使它们易于访问和初始化。

答案 5 :(得分:1)

我们使用BaseController做两件事:

  1. 应应用于所有控制器的属性。
  2. 重定向重定向,通过检查重定向URL是本地URL来防止打开重定向攻击。这样,调用Redirect的所有控制器都受到保护。

答案 6 :(得分:1)

我所做的是使用通用控制器基类来处理:

  • 我创建了BaseCRUDController<Key,Model>,其中需要ICRUDService<TModel>个对象作为构造函数参数,因此基类将处理创建 / 编辑 / 删除即可。并确保在虚拟模式下处理自定义情况
  • ICRUDService<TModel>包含保存 / 更新 / 删除 / 查找 / ResetChache / ...我为我创建的每个存储库实现它,这样我就可以为它添加更多功能。
  • 使用此结构我可以添加一些常规功能,例如 PagedList / 自动完成 / ResetCache / IncOrder&amp; DecOrder (如果模型是IOrderable)
  • 错误 / 通知消息处理:布局中包含@TempData["MHError"]代码的部分和基础控制器中的属性

    公共通知错误         {             set {TempData [“MHError”] = value; }             get {return(Notification)TempData.Peek(“MHError”); }         }

使用这个抽象类,我可以轻松处理每次必须编写或使用代码生成器创建的方法。 但这种做法也有它的弱点。

答案 7 :(得分:1)

我现在使用基本控制器使用i18N库进行国际化。它提供了一种方法,可用于本地化控制器中的任何字符串。

答案 8 :(得分:0)

过滤器不是线程安全的,数据库访问和依赖注入的条件,数据库连接可能在使用时被其他线程关闭。