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

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

          • 内容协商 (Content Negotiation)
          • Accept Header
          • Content-Type Hander
          • Accept Hander 与 Content-Type Hander 的应用
          • 下面开始写代码对上理论进行验证

内容协商 (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 内容协商_第1张图片
返回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 内容协商_第2张图片

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

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

此处我们需要注意:千万不能在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.

  • 以上文档参考自
    内容协商P7
    内容协商p8

你可能感兴趣的:(使用ASP.NET Core 3.x 构建 RESTful API P7 P8 内容协商)