ASP.NET Core中的Controller
asp.net core出现之前我们实现的controller,mvc都继承自controller基类,webapi的话继承自apicontroller。现在asp.net core把mvc跟webapi合并了,已经不再区分mvc或者webapi。asp.net core的controller继承结构也发生了变化。我们看其他示例的时候会发现有些继承自controller有些继承自controllerbase。事实上controllerbase是controller的基类。也就是说如果你继承自controller,其实就是继承了controllerbase。那什么时候该选择直接继承controllerbase呢?
controllerbase
我们先看看controllerbase的元数据:
很长并没有截全。可以看到controllerbase是个抽象类,并且实现了大量的虚方法。这些虚方法大都是对应了http的状态码。
比如:
public virtual okresult ok(); //http status 200 public virtual notfoundresult notfound(); //http status 404 public virtual forbidresult forbid(); //http status 403 public virtual createdresult created(uri uri, [actionresultobjectvalue] object value); // http status 201 ...还有很多很多...
显然这是为restful api设计的基类,所以当你要设计一个restful(web api)接口的时候可以选择继承自controllerbase,它已经可以满足你的需求。
controller
查看下controller的元数据:
controller也是一个抽象类,继承自controllerbase,并且继承了几个接口。很明显controller比controllerbase多的内容主要是一些跟mvc打交道的东西。
比如:viewbag、viewdata属性,json、view方法等:
public dynamic viewbag { get; } public viewdatadictionary viewdata { get; set; } public virtual jsonresult json(object data); public virtual viewresult view(); ...
所以如果你是需要实现一个mvc系统,想要使用cshtml模板跟razor试图引擎渲染页面则需要继承controller。
poco controller
除了继承controller、controllerbase之外,asp.net core框架可以让你的poco类直接变成controller。
使用“controller”后缀
下面的代码,testcontroller可以正常工作吗?
[route("api/[controller]")] public class testcontroller { [httpget] public string get() { return "testcontroller"; } }
运行一下:
虽然testcontroller类并没有继承自任何类,但是他确实可以在asp.net core框架内正常工作。asp.net core框架默认会查找后缀为“controller”的类,并把它当做真正的controller使用,在路由系统最终匹配controller的时候它也会被尝试匹配。
使用controllerattribute
如果你的控制器类有什么特别需求,连类名都不想加入“controller”的后缀,那么还有一种方法就是使用controllerattribute。
[controller] [route("api/[controller]")] public class poco { [httpget] public string get() { return "pococontroller"; } }
运行一下:
poco类并没有继承自任何类,并且也没有“controller”后缀命名,但是因为它被标记了controllerattribute同样会被asp.net core框架认为是一个controller。在路由系统最终匹配controller的时候它也会被尝试匹配。
使用noncontrollerattribute
如果你的一个类名恰巧包含“controller”的后缀,但你并不想asp.net core框架发现它,你可以在类上加上noncontrollerattribute。这样asp.net core框架就会忽略它。
改一下刚才的testcontroller,加上[noncontroller]:
[noncontroller] [route("api/[controller]")] public class testcontroller { [httpget] public string get() { return "testcontroller"; } }
运行一下:
/api/test已经匹配不到controller了。
总结
- 设计restful(web api)接口的时候可以继承controllerbase
- 设计mvc系统的时候可以继承controller
- 当一个poco类名称包含"controller"后缀或添加controllerattribute的时候框架会认为这是一个控制器
- 当一个类不想被框架当做控制器的时候可以添加noncontrollerattribute
推荐阅读
-
ASP.NET Core基于微软微服务eShopOnContainer事件总线EventBus的实现
-
在ASP.NET中实现多文件上传的方法
-
ASP.Net中防止刷新自动触发事件的解决方案
-
ASP.NET Core中预压缩静态文件的方法步骤
-
你所不知道的ASP.NET Core MVC/WebApi基础系列 (一)
-
灵活掌握Asp.net MVC中GridView的使用方法
-
Asp.net中Microsoft.Identity的IPasswordHasher加密的默认实现与运用
-
在asp.net中实现datagrid checkbox 全选的方法
-
ASP.NET Core 2.2中的Endpoint路由详解
-
详解.NET Core 3.0中的新变化