【ASP.NET Core】根据 Content-Type 头部来筛选 Action

在开始今天的吹牛节目之前,老周先说个破事:每周的周五或者周六,老周会在新浪直播平台(一直播同步)开播 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 方法,所以,第一步与第三步测试的结果相同。

 

好了,今天的吹牛节目完成了,下次老周与你继续扯。

 

posted @ 2018-03-12 18:23  东邪独孤  阅读(3875)  评论(3编辑  收藏  举报