在开始今天的吹牛节目之前,老周先说个破事:每周的周五或者周六,老周会在新浪直播平台(一直播同步)开播 ASP.NET Core 相关的内容。具体的直播时间老周会在微博上发布。直播是免费观看的,当然了,如果你钱多的话,也可以赞助老周几个欧元的。
好,进入今天的主题。留个悬念,老周不告诉你扯什么,先看一个例子。
[Route("/api/[controller]/[action]")] public class DemoController : Controller { [ActionName("send"), HttpGet] public IActionResult Send_Ver1() { return Content("你访问的是版本 1 的接口,此接口提供给畜生使用。"); } [ActionName("send")] [HttpGet] public IActionResult Send_Ver2() { return Content("你访问的是版本 2 的接口,该接口提供给人渣使用。"); } }
这是一个控制器类,因为没有 View 返回,也可以认为是一个 Web API。
关键注意这两个 Attribute。
ActionName("send") ActionName("send")
类中有两个方法,分别命名为 Send_Ver1 和 Send_Ver2,由于我在它们上面使用了 ActionNameAttribute,并且指定了这两个方法所公开的 Action 名字都叫 send。
如此一来,疑问就产生了,两个同名的 action ,应用程序在运行阶段该如何选择呢。
来,试试看。
电脑毕竟不是人脑,它不会思考的,所以,运行的时候应用程序是无法做出选择了。
一般真的开发的话,没有人这么干的,弄两个一样的 action 干屌,不过,为了接下来的演示,老周决定干一次屌。这个时如果你非得坚持使用两个同名 action ,那么,你可以通过客户端调用时传递的 content-type Header 来区别这两个 action。
于是,你可以对上面的代码做这样修改,应用一个 ConsumesAttribute 就好了,当然了,重点是你得指定 Content-Type。
[Route("/api/[controller]/[action]")] public class DemoController : Controller { [ActionName("send"), HttpGet] [Consumes("application/pdf")] public IActionResult Send_Ver1() { …… } [ActionName("send")] [HttpGet] [Consumes("audio/DV")] public IActionResult Send_Ver2() { …… } }
这样改动之后,在发起请求时,如果指定 content-type 为 application/pdf,那么调用会进入 Send_Ver1 方法;如果请求时指定的 content-type 是 audio/DV,那么就会进入 Send_Ver2 方法。
这个 ConsumesAttribute 在实例化时,还可以指定多个 content-type。因为它有这样的构造函数。
public ConsumesAttribute(string contentType, params string[] otherContentTypes)
比如咱们这个示例,如果希望带 application/PDF 和 application/XML 的 Content-Type 都能进入 Send_Ver1 方法,那么你可以这么做。
[Consumes("application/pdf", "application/xml")] public IActionResult Send_Ver1() { ……
}
现在咱们再来测试一下。
第一步,携带 content-type = application/pdf 调用 web api。
第二步,把 Content-Type 改为 audio/DV,再发起一次请求。
第三步,把 Content-Type 改为 application/xml ,再试试。
因为上面咱们指定了,application/pdf 和 application/xml 的 content type 都可以进入 Send_Ver1 方法,所以,第一步与第三步测试的结果相同。
好了,今天的吹牛节目完成了,下次老周与你继续扯。