什么是ASP.NET MVC基础控制器类的好select?
我见过很多人谈论在他们的ASP.NET MVC项目中使用基本控制器。 我见过的典型例子是用于伐木或CRUD脚手架。 什么是基础控制器类的其他一些好的用途?
基础控制器类没有很好的用途。
现在听我说。
Asp.Net MVC,尤其是MVC 3具有大量的可扩展性钩子,为所有控制器增加了function。 由于您的控制器类对于应用程序来说非常重要且非常重要,因此让它们保持轻量级,敏捷性和松散耦合性是非常重要的。
-
logging基础设施属于构造函数,应通过DI框架注入。
-
CRUD脚手架应由代码生成或自定义ModelMetadata提供程序处理。
-
全局exception处理应该由一个自定义的ActionInvoker处理。
-
全局视图数据和授权应该由动作filter处理。 使用MVC3中的全局动作filter更容易。
-
常量可以进入另一个名为ApplicationConstants的类/文件。
基本控制器通常由没有经验的MVC开发人员使用,他们不知道MVC的所有不同的扩展性部分。 现在请不要误解我的意思,我不是在判断和处理那些使用它们的人所有错误的理由。 它的正义体验为您提供了解决常见问题的更多工具。
我几乎肯定有没有一个问题,你不能解决与另一个扩展钩子比基础控制器类。 除非有明显的生产力原因,并且不违反Liskov,否则不要采用最紧密的耦合forms(inheritance)。 我宁愿采取<1秒,在我的控制器上键入一个属性20次,如public ILogger Logger { get; set; }
public ILogger Logger { get; set; }
public ILogger Logger { get; set; }
不是引入一个紧密耦合,以更重要的方式影响应用程序。
即使像userId或multitenant键的东西也可以进入ControllerFactory而不是基本控制器。 基本控制器类的耦合成本是不值得的。
我喜欢使用基本控制器进行授权。
我没有使用“授权”属性来装饰每个动作,而是在基础控制器中进行授权。 授权操作列表是从login用户的数据库中提取的。
请阅读下面的链接获取更多关于授权的信息。 在自定义控制器工厂中进行通用授权的良好做法?
我用它来访问会话,应用程序数据等
我也有一个应用程序对象,其中包含应用程序名称等的东西,我从基类访问
基本上我用它来重复很多事情
哦,我应该提到我不使用它的buisiness逻辑或数据库访问。 常量对于基类来说也是一个不错的select。
根据我的经验,大部分你想放在基本控制器中的逻辑理想情况下都会进入一个动作filter。 Action Filter只能用常量初始化,所以在某些情况下你不能这样做。 在某些情况下,您需要将操作应用到系统中的每个操作方法,在这种情况下,将逻辑放在基础中而不是使用新的actionFilter属性注释每个操作方法会更有意义。
我还发现将引用服务的属性(与控制器相分离)放入基础中会很有帮助,这使得它们可以一致地访问和初始化。
我在我的很多项目中都使用了基础控制器,并且工作得非常棒。 我主要用于
- exceptionlogging
- 通知(成功,错误,添加..)
- 调用HTTP404error handling
我们使用BaseController来做两件事情:
- 应该应用于所有控制器的属性。
- 重写redirect,通过检查redirectURL是否为本地URL来防止redirect攻击。 这样所有调用redirect的控制器都受到保护。
我正在使用i18N库进行国际化的基本控制器。 它提供了一种方法,可以用来本地化控制器内的任何string。
我所做的是使用通用控制器基类来处理:
- 我创build了
BaseCRUDController<Key,Model>
,它需要一个ICRUDService<TModel>
对象作为构造参数,所以基类将处理Create / Edit / Delete 。 并确保在虚拟模式下处理自定义情况 -
ICRUDService<TModel>
具有像保存 / 更新 / 删除 / 查找 / ResetChache / …方法,我实现它为我创build的每个存储库,所以我可以添加更多的function。 - 使用这种结构,我可以添加一些常规function,如PagedList / AutoComplete / ResetCache / IncOrder&DecOrder (如果模型是IOrderable)
-
错误 / 通知消息处理:布局中带有
@TempData["MHError"]
代码的部分和基本控制器中的属性公共通知错误{set {TempData [“MHError”] = value; } get {return(Notification)TempData.Peek(“MHError”); }}
有了这个抽象类,我可以很容易地处理我不得不每次编写或使用代码生成器创build的方法。 但是这个方法也有弱点。
filter不是线程安全的,数据库访问和dependency injection的条件,数据库连接在使用时可能会被其他线程closures。