ASP.NET Core MVC 中的 [Controller] 和 [NonController]
前言
我们知道,在 MVC 应用程序中,有一部分约定的内容。其中关于 Controller 的约定是这样的。
- 每个 Controller 类的名字以 Controller 结尾,并且放置在 Controllers 目录中。
- Controller 使用的视图是在 Views 主目录的一个子目录中,这个子目录是根据控制器名称(后面减去Controller后缀)来命名的。
明白了以上约定之后,就来一起看看下面吧。
Controller VS NonController 中内置的约定
在 ASP.NET Core MVC 中已经统一了 MVC 和 Web Api 及 Web Pages, 他们具有相同的 Controller ,并且在 RC2 之后的版本中,ASP.NET Core MVC 支持了 POCO Controller,所以你在做一个 Web Api 的 Controller 的时候不需要再继承自 Controller 基类。
POCO Controller 即 public 的,非抽象的,没有任何继承,不实现任何接口的 Controller 类,类似于 POCO Class,仅仅是以 Controller 结尾而已。
到这里,有些同学可能会问了,在 POCO Controller 中如果我想获取 HTTP 上下文的一些东西应该怎么获取呢? 嗯?。。。 这确实是个问题。。。。怎么办呢? 老实的继承基类 Controller 吧,因为 Vnext 中的 POCO Controller 属性注入已经被取消了。
如果你创建了一个 POCO Controller ,那么他们的名字必须以 Controller 结尾,只有这样他们才是一个有效的 Controller,不然的话,MVC 不会认为你这是一个 Controller 对象。即使你具有 Route 之类的标记也不可以。
所以,在创建一个 MVC Controller 的时候,就有两个先决条件:
- -- 继承自 Controller 基类
- -- 或者使用一个以 Controller 结尾的名字
下面是创建两种 Controller 的一个 Web Api Controller示例:
[Route("api/[controller]")]
public class FooController : Controller
{
[HttpGet]
public string Get()
{
return "foo";
}
}
[Route("api/[controller]")]
public class BarController
{
[HttpGet]
public string Get()
{
return "bar";
}
}
现在有同学可能会问了,第一个既然已经继承了 Controller 基类,再在定义 Controller 的时候还要加 Controller 后缀不是多此一举么?这样写可不可以呢?
[Route("api/[controller]")]
public class Foo : Controller
{
[HttpGet]
public string Get()
{
return "foo";
}
}
好吧,这样子也是正确的。为什么呢?这是因为继承的基类 Controller 已经被打上了 ControllerAttribute 的标记,打上了这个标记之后,在构建扫描的时候就会被认为是一个 Controller,也就是说整个继承树已经被认为是一个有效的 MVC Controller 了。
那么,有同学又问了,这样可不可以呢?
[Route("api/[controller]")]
public class Bar
{
[HttpGet]
public string Get()
{
return "bar";
}
}
这样子是不行的,因为这是一个 POCO Controller,没有任何标记使 MVC 框架会认为这是一个有效的Controller,这个时候,如果 如果想让框架认为这是一个有效的 Controller,可以通过添加 ControllerAttribute 的方式:
[Controller]
[Route("api/[controller]")]
public class Bar
{
[HttpGet]
public string Get()
{
return "bar";
}
}
这个时候,MVC 框架就会认为这是个有效的 Controller 了。
同样的,这样的代码也是有效的,因为基类已经有了 ControllerAttribute 标记 :
[Controller]
public class ApiBase {}
[Route("api/[controller]")]
public class Bar : ApiBase
{
[HttpGet]
public string Get()
{
return "bar";
}
}
还有一种可能性,就是当你有一个类,它恰好是以 Controller 结尾,但是实际上并不是一个 Controller 类怎么办呢? 这个时候,你就需要添加一个 NonControllerAttribute 标记,来声明当前的类并不是一个 MVC 的 Controller 类,从而避免在构建的时候,框架会认错。
[NonController]
public class DemoController
{
// 非 action 代码
}
有一点需要注意的是,NonControllerAttribute 标记比 ControllerAttribute 具有更高的优先级,所以当一个 Controller 同时具有这两个标记的时候,会以 NonControllerAttribute 为准。
实际上,只要是整个 Controller 继承树中有一个 Controller 被标记为 NonControllerAttribute 的时候,整个继承树的 Controller 均会被认为是无效的 Controller 了。
本文地址:http://www.cnblogs.com/savorboard/p/dontnet-controller.html
作者博客:Savorboard
欢迎转载,请在明显位置给出出处及链接
ASP.NET Core MVC 中的 [Controller] 和 [NonController]的更多相关文章
- 在ASP.NET Core MVC中子类Controller拦截器要先于父类Controller拦截器执行
我们知道在ASP.NET Core MVC中Controller上的Filter拦截器是有执行顺序的,那么如果我们在有继承关系的两个Controller类上,声明同一种类型的Filter拦截器,那么是 ...
- 006.Adding a controller to a ASP.NET Core MVC app with Visual Studio -- 【在asp.net core mvc 中添加一个控制器】
Adding a controller to a ASP.NET Core MVC app with Visual Studio 在asp.net core mvc 中添加一个控制器 2017-2-2 ...
- ASP.NET MVC和ASP.NET Core MVC中获取当前URL/Controller/Action (转载)
ASP.NET MVC 一.获取URL(ASP.NET通用): [1]获取完整url(协议名+域名+虚拟目录名+文件名+参数) string url=Request.Url.ToString(); [ ...
- ASP.NET Core MVC中Controller的Action,默认既支持HttpGet,又支持HttpPost
我们知道ASP.NET Core MVC中Controller的Action上可以声明HttpGet和HttpPost特性标签,来限制可以访问Action的Http请求类型(GET.POST等). 那 ...
- ASP.NET Core MVC中的IActionFilter.OnActionExecuting方法,可以获取Controller的Action方法参数值
用过ASP.NET Core MVC中IActionFilter拦截器的开发人员,都知道这是一个非常强大的MVC拦截器.最近才发现IActionFilter的OnActionExecuting方法,甚 ...
- ASP.NET Core MVC中的IActionFilter.OnActionExecuted方法执行时,Controller中Action返回的对象是否已经输出到Http Response中
我们在ASP.NET Core MVC项目中有如下HomeController: using Microsoft.AspNetCore.Mvc; namespace AspNetCoreActionF ...
- ASP.NET Core MVC中Controller的Action如何直接使用Response.Body的Stream流输出数据
在ASP.NET Core MVC中,我们有时候需要在Controller的Action中直接输出数据到Response.Body这个Stream流中,例如如果我们要输出一个很大的文件到客户端浏览器让 ...
- 008.Adding a model to an ASP.NET Core MVC app --【在 asp.net core mvc 中添加一个model (模型)】
Adding a model to an ASP.NET Core MVC app在 asp.net core mvc 中添加一个model (模型)2017-3-30 8 分钟阅读时长 本文内容1. ...
- ASP.NET Core MVC中构建Web API
在ASP.NET CORE MVC中,Web API是其中一个功能子集,可以直接使用MVC的特性及路由等功能. 在成功构建 ASP.NET CORE MVC项目之后,选中解决方案,先填加一个API的文 ...
随机推荐
- jquery.uploadify文件上传组件
1.jquery.uploadify简介 在ASP.NET中上传的控件有很多,比如.NET自带的FileUpload,以及SWFUpload,Uploadify等等,尤其后面两个控件的用户体验比较好, ...
- 前端框架 EasyUI (2)页面布局 Layout
在 Web 程序中,页面布局对应用程序的用户体验至关重要. 在一般的信息管理类的 Web 应用程序中,页面结构通常有一个主工作区,然后在工作区上下左右靠近边界的区域设置一些边栏,用于显示信息或放置一些 ...
- ASP.NET Core HTTP 管道中的那些事儿
前言 马上2016年就要过去了,时间可是真快啊. 上次写完 Identity 系列之后,反响还不错,所以本来打算写一个 ASP.NET Core 中间件系列的,但是中间遇到了很多事情.首先是 NPOI ...
- Redis/HBase/Tair比较
KV系统对比表 对比维度 Redis Redis Cluster Medis Hbase Tair 访问模式 支持Value大小 理论上不超过1GB(建议不超过1MB) 理论上可配置(默认配置1 ...
- 引人瞩目的 CSS 变量(CSS Variable)
这是一个令人激动的革新. CSS 变量,顾名思义,也就是由网页的作者或用户定义的实体,用来指定文档中的特定变量. 更准确的说法,应该称之为 CSS 自定义属性 ,不过下文为了好理解都称之为 CSS 变 ...
- .net 分布式架构之业务消息队列
开源QQ群: .net 开源基础服务 238543768 开源地址: http://git.oschina.net/chejiangyi/Dyd.BusinessMQ ## 业务消息队列 ##业务消 ...
- 对Thoughtworks的有趣笔试题实践
记得2014年在网上看到Thoughtworks的一道笔试题,当时觉得挺有意思,但是没动手去写.这几天又在网上看到了,于是我抽了一点时间写了下,我把程序运行的结果跟网上的答案对了一下,应该是对的,但是 ...
- CSS——关于z-index及层叠上下文(stacking context)
以下内容根据CSS规范翻译. z-index 'z-index'Value: auto | <integer> | inheritInitial: autoApplies to: posi ...
- BridgePattern(桥接模式)
/** * 桥接模式 * @author TMAC-J * 应用于多维度方案 * 用组合的形式代替继承 * 符合单一职责原则 * 一个类只有一个引起他变化的原因 * 增加程序灵活性 */ public ...
- 港真,到底应该选择OA还是BPM?
越来越多企业意识到流程管理的重要性,但是,选择OA还是BPM,却让他们产生了选择困难症. 一方面,企业皆注重流程的高效运转,最好内外部的业务都能用一个系统来解决.所有流程一天就能上线什么的,那就更好啦 ...