什么是ASP.NET MVC基础控制器类的好选择?

什么是ASP.NET MVC基础控制器类的好选择?

问题描述:

我见过很多人谈论在他们的ASP.NET MVC项目中使用基础控制器。我见过的典型例子是用于伐木或CRUD脚手架。基础控制器类有什么其他的好用途?什么是ASP.NET MVC基础控制器类的好选择?

基控制器类没有什么好用处。

现在听我说。

Asp.Net MVC,尤其是MVC 3拥有吨的可扩展的钩子提供更解耦的方式将功能添加到所有控制器。由于您的控制器类对于应用程序来说非常重要且非常重要,因此让它们保持轻量,敏捷和松散耦合到其他所有方面非常重要。

  • 日志基础设施属于一个 构造,并应通过DI框架注入 。

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

  • 全球的异常处理应该由定制ActionInvoker被 处理。

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

  • 常量可以去另一个类/文件名为ApplicationConstants什么的。

基地控制器通常使用由缺乏经验的开发者MVC谁不知道所有MVC的不同扩展件。现在,请不要误解我的意思,我不会评判并与那些因为所有错误原因而使用它们的人一起工作。它的正义体验为您提供了解决常见问题的更多工具。

,我几乎可以肯定没有,你不能与其他可扩展性挂钩不是一个基本的控制器类解决一个单一的问题。除非有明显的生产力原因,并且不违反Liskov,否则不要采用最紧密的耦合形式(继承)。我宁愿花1秒钟在public ILogger Logger { get; set; }之类的控制器上键入一次属性20次,而不是引入紧密耦合,这会以更重要的方式影响应用程序。

即使像用户标识或者多租户键可以走了的ControllerFactory而不是基本控制器。基础控制器类的耦合成本是不值得的。

+2

好了,我们可以做的事情,而不使用基本控制器。你能告诉使用基本控制器 – Tassadaque 2011-05-26 06:30:47

+6

@Tassadaque的一些缺点 - 联轴器,联轴器,联轴器和耦合。 – jfar 2011-05-26 13:07:11

+29

我不相信。你更喜欢在所有的控制器中使用相同的代码,而不是拥有一个基础控制器,所以必须有这个优势。你说优势是“松散耦合”,但究竟是什么意思,它解决了哪些问题,它除了解耦以外还有什么其他问题? – Stijn 2013-02-13 13:18:49

我将其用于访问会话,应用程序数据等

我也有保持之类的应用程序的名称等的应用对象和我访问从基类

基本上我使用它因为我重复了很多事情

噢,我应该提到我不使用它的buisiness逻辑或数据库访问。我猜,常量对于基类来说是一个不错的选择。

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

我还发现它有助于把属性引用服务(否则从控制器分离)为基础,使它们易于访问和持续初始化。

+2

ActionFilters只能用常量进行初始化并不是真的。常量的初始化是属性的一个特性,而不是IActionFilter接口。您可以创建您的动作过滤器,然后将其分配给您的过滤器配置中的GlobalFilterCollection,或者无论您在何处处理此类事情。在您的过滤器中,您只需检查是否存在您创建的单独属性,然后继续使用过滤器的逻辑。 – crush 2015-06-19 19:53:14

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

相反装潢每个动作的“授权”属性,我做授权的基本控制器。授权操作列表是从登录用户的数据库中获取的。

请阅读下面的链接以获得更多关于授权的信息。 Good practice to do common authorization in a custom controller factory?

我们使用BaseController两件事情:应该适用于所有控制器

  1. 属性。
  2. 重写重定向,通过检查重定向URL是否为本地URL来防止重定向攻击。这样所有调用重定向的控制器都受到保护。
+0

你的第二点不是很清楚。如何覆盖基本控制器中的重定向?会拿出一些例子,比如如何去做。如果可能的话,将教育我如何开放重定向攻击发生以及如何通过示例阻止基类。谢谢 – Mou 2015-09-15 13:36:36

+0

1)可以用[全局注册的过滤器](https://msdn.microsoft.com/en-us/library/gg416513(VS.98).aspx)代替。更好的是,自定义过滤器可以使用自定义属性来有条件地排除它们(这将是重写时在基础控制器中维护的噩梦)。 2)这种孤立的逻辑可以放在Controller类的扩展方法中。无需到处继承自定义的基本控制器(也不必担心最终会在某处忘记这么做)。 – NightOwl888 2016-06-01 16:30:45

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

  • 我创建BaseCRUDController<Key,Model>这需要ICRUDService<TModel>对象作为构造函数的参数,因此基类将处理创建/编辑/删除。并确保在虚拟模式,自定义的情况下处理
  • ICRUDService<TModel>已经像保存/更新/方法删除/查找/ResetChache/......我实现它为我创建的每个存储库所以我可以添加更多的功能。
  • 采用这种结构我可以添加像PagedList一些一般功能/自动完成/ResetCache/IncOrder & DecOrder(如果模型IOrderable)
  • 错误/通知消息处理:在布局一部分与@TempData["MHError"]代码和类似

    PU在碱控制器一个属性blic通知错误 set {TempData [“MHError”] = value; } get {return(Notification)TempData。PEEK( “MHError”); }}

有了这个抽象类,我可以很容易地处理方法,我不得不每次写或代码生成器创建。 但是这种方法也有弱点。

我使用了一个基本的控制器现在国际使用i18N库。它提供了一种我可以用来本地化控制器内任何字符串的方法。

我已经在我的许多项目中使用的基本控制器和工作太棒了。我主要用于

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

你会将我重定向到一些文章,比如如何通过基本控制器来处理你的情况。情况就像'异常日志记录,通知(成功,错误,添加..)和HTTP404错误处理'感谢 – Mou 2015-09-15 13:38:21

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