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的文 ...
随机推荐
- 日期格式代码出现两次的错误 ORA-01810
错误的原因是使用了两次MM . 一.Oracle中使用to_date()时格式化日期需要注意格式码 如:select to_date('2005-01-01 11:11:21','yyyy-MM-dd ...
- Windows 7上执行Cake 报错原因是Powershell 版本问题
在Windows 7 SP1 电脑上执行Cake的的例子 http://cakebuild.net/docs/tutorials/getting-started ,运行./Build.ps1 报下面的 ...
- InnoDB关键特性学习笔记
插入缓存 Insert Buffer Insert Buffer是InnoDB存储引擎关键特性中最令人激动与兴奋的一个功能.不过这个名字可能会让人认为插入缓冲是缓冲池中的一个组成部分.其实不然,Inn ...
- 关于 CSS 反射倒影的研究思考
原文地址:https://css-tricks.com/state-css-reflections 译者:nzbin 友情提示:由于演示 demo 的兼容性,推荐火狐浏览.该文章篇幅较长,内容庞杂,有 ...
- AFNetworking 3.0 源码解读 总结(干货)(下)
承接上一篇AFNetworking 3.0 源码解读 总结(干货)(上) 21.网络服务类型NSURLRequestNetworkServiceType 示例代码: typedef NS_ENUM(N ...
- js从数组中随机取出不同的元素
前言 上午处理个需求需要从一个总数组中随机取出不同的元素.共使用两个方法.第一种方法较常规,经测试有bug,数据量大以后随机几次返回的对象直接是function而不是object. 当然简单数据类型应 ...
- Android中使用ViewFlipper实现屏幕页面切换(关于坐标轴的问题已补充更改)
屏幕切换指的是在同一个Activity内屏幕间的切换,ViewFlipper继承了Framelayout类,ViewAnimator类的作用是为FrameLayout里面的View切换提供动画效果.如 ...
- 1.Hibernate简介
1.框架简介: 定义:基于java语言开发的一套ORM框架: 优点:a.方便开发; b.大大减少代码量; c.性能稍高(不能与数据库高手相比,较一般数据库使用者 ...
- oracle 存储过程
来自:http://www.jb51.net/article/31805.htm Oracle存储过程基本语法 存储过程 1 CREATE OR REPLACE PROCEDURE 存储过程名 2 I ...
- 【番外篇】ASP.NET MVC快速入门之免费jQuery控件库(MVC5+EF6)
目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...