使用ASP.NET Core 3.x 构建 RESTful API P7 P8 内容协商

使用ASP.NET Core 3.x 构建 RESTful API P7 P8 内容协商

内容协商 (Content Negotiation)

人们经常将 RESTful APIJson 联系在一起,是因为 Json
RESTful API 表述,结果的一种方式,但是 RESTful API表述结果,不仅仅会使用 Json ,也有可能会使用 XML ,以及一些其它自定义的数据格式,那么到底需要 RESTful API 返回什么样的数据格式类型呢?那么这就叫做 内容协商,即 API 消费者需要明确的告知, API 它需要什么样的返回结果的数据格式,以便返回的结果,能够得到顺利的解析.

  • 内容协商:针对一个响应,当有多种表示格式可用的时候,选取最佳的一个表述.
Accept Header

在请求报文中 Accept Hander 是用来告诉Api,消费者需要API来返回什么样格式的数据.

  • Media Type (媒体类型)
    • application/json
    • application/xml
    • ...
  • 如果消费者没有告诉 API 它需要的数据格式,那么 API 会以 API 自己默认的数据格式返回数据.
  • 如果 消费者 明确告知了 API 自己需要的数据格式,但是 API 不支持这种数据格式,那么 API 就应该返回 406HTTP Status Code ,即 Not Acceptable
  • 输出格式
  • 在 ASP .NET Core 里面对应的就是 Output Formatters
Content-Type Hander

在请求报文中 Content-Type 是用来告诉 API,消费者传递过来的数据的格式是什么样的,以便 API 可以方便的解析消费者的请求参数.

  • Media Type(媒体类型)

    • application/json
    • application/xml
    • ...
  • 输出格式

  • ASP .NET Core 里面对应的就是Input formatters.

Accept Hander 与 Content-Type Hander 的应用

在默认情况下 ASP .Net Core 使用 JSON 作为数据输入和输出的格式化器.

下面开始写代码对上理论进行验证

如当消费者要求的返回格式,API 不支持,那么 API 应该返回相应的 HTTP 状态码.

为此在 ASP .Net Core 中,我们需要在 Startup.cs 文件的 ConfigureServices 方法中编写以下代码:

 services.AddControllers(setup =>
            {
                //例子:当消费者要求返回的数据格式是json时,如果服务器端默认的就是xml格式,而且仅仅只支持xml格式,
                //那么默认的就会将xml格式返回回去,并且不会返回406状态码,所以ReturnHttpNotAcceptable的默认值就是false
                //setup.ReturnHttpNotAcceptable = false;

                //当为true时,表示当消费者要求的返回的数据类型,与数据库支持的返回的数据类型不一致时,
                //就会返回 HTTP 状态码 406 ,也就是NotAcceptable
                setup.ReturnHttpNotAcceptable = true;
            });

当我们将 ReturnHttpNotAcceptable 的值设置为true时,表示当消费者要求返回的数据格式,不被服务器所支持,那么服务器就会返回406,如图:

使用ASP.NET Core 3.x 构建 RESTful API P7 P8 内容协商
返回406

那么我们让我们的 API 既支持json格式的返回,也支持xml格式的返回呢?
我们可以将代码这么写,如下:

     services.AddControllers(setup =>
            {
                //例子:当消费者要求返回的数据格式是json时,如果服务器端默认的就是xml格式,而且仅仅只支持xml格式,
                //那么默认的就会将xml格式返回回去,并且不会返回406状态码,所以ReturnHttpNotAcceptable的默认值就是false
                //setup.ReturnHttpNotAcceptable = false;

                //当为true时,表示当消费者要求的返回的数据类型,与数据库支持的返回的数据类型不一致时,
                //就会返回 HTTP 状态码 406 ,也就是NotAcceptable
                setup.ReturnHttpNotAcceptable = true;


                //OutputFormatters是一个集合,这个集合里面可以放置多个格式化器,用来支持多种消费者要求的返回格式,
                //这OutputFormatters中的第一个元素设置,就是这个集合默认的返回格式的格式化器,默认情况下OutputFormatters
                //中只有一个json格式化器.

                //下面我们添加对xml格式化器的支持
                //setup.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());

                //如果我们想添加xml格式化器,并使其成为默认的数据格式化器,那么我们使用如下写法即可:
                //那么当消费者没有要求返回格式时,API会默认返回xml格式的数据.
                setup.OutputFormatters.Insert(0, new XmlDataContractSerializerOutputFormatter());
            });

请求返回的数据如下:
使用ASP.NET Core 3.x 构建 RESTful API P7 P8 内容协商

请求返回的数据格式如下:
使用ASP.NET Core 3.x 构建 RESTful API P7 P8 内容协商

此时我们要求 API 返回Json格式的数据也是可以的,因为 API也支持了返回Json的设置,如下:
使用ASP.NET Core 3.x 构建 RESTful API P7 P8 内容协商

此处我们需要注意:千万不能在Action中使用return new JsonResult(对象);的形式来返回数据,否则就不能根据消费者要求的数据格式来返回数据了.

那么我们如何支持输入参数的数据格式的支持呢?
使用方式和 OutputFormatters是一样的存在一个叫InputFormatters,它的使用方式和OutputFormatters, 是一样的,代码如下:

 //添加对请求参数格式是xml的支持
                setup.InputFormatters.Insert(0,new XmlDataContractSerializerInputFormatter(setup));

但是上述写法都只是 ASP .Net Core 3.x 之前的写法,在3.x 之后的写法是这样的,代码如下:

services.AddControllers(setup =>
            {
             
                setup.ReturnHttpNotAcceptable = true;
                
            }).AddXmlDataContractSerializerFormatters();

我们可以接在 AddControllers() 方法之后,接着写 .AddXmlDataContractSerializerFormatters()方法即可,它既表明支持消费者传入的参数是xml格式,也支持消费者要求的返回数据格式是xml.

使用ASP.NET Core 3.x 构建 RESTful API P7 P8 内容协商

上一篇:windows10环境下QtCreator中出现skipping incompatible xxx when searching for xxx 问题解决办法


下一篇:C# 获取屏幕的大小