首页 > 其他分享 >第20章 高级Web服务特性

第20章 高级Web服务特性

时间:2024-04-24 09:36:37浏览次数:19  
标签:Web 20 特性 id Content json supplier return public

1 准备工作

添加SuppliersController控制器。

    [ApiController]
    [Route("api/[controller]")]
    public class SuppliersController:ControllerBase
    {
        private DataContext _context;
        public SuppliersController(DataContext dataContext)
        {
            _context = dataContext;
        }
        [HttpGet("{id}")]
        public async Task<Supplier> GetSupplier(long id)
        {
            Supplier supplier = await _context.Suppliers.FindAsync(id);
            return supplier;
        }
    }

2 处理相关数据

当使用Include方法时,EFCore可通过数据库中的关系填充导航属性。

        [HttpGet("{id}")]
        public async Task<Supplier> GetSupplier(long id)
        {
            Supplier supplier = await _context.Suppliers
                .Include(s => s.Products)
                .FirstAsync(s => s.SupplierId == id);
            return supplier;
        }

但是这样会导致报错:对象循环。因为Suppliers和Product对象的导航属性之前创建了一个循环引用。

打破循环引用最简单的办法如下。

            foreach (Product p in supplier.Products)
            {
                p.Supplier = null;
            };
            return supplier;

3 支持HTTP Patch方法

使用Patch请求只向Web服务发送更改,而不是完整地替换对象。

3.1 理解JSON Patch

客户端会在HTTP Patch请求中发送Web服务Json数据,如下:

[
    {"op":"replace","path":"Name","value":"abc"},
]

3.2 安装和配置JSON Patch

安装JSON Patch包

dotnet add package Microsoft.AspNetCore.Mvc.NewtonsoftJson --version 3.1.1

在Startup方法中启用序列化器。

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<DataContext>(opts =>
            {
                opts.UseSqlServer(Configuration["ConnectionStrings:ProductConnection"]);
                opts.EnableSensitiveDataLogging(true);
            });
            services.AddControllers().AddNewtonsoftJson(); 
            services.Configure<MvcNewtonsoftJsonOptions>(opts =>
            {
                opts.SerializerSettings.NullValueHandling
                    = Newtonsoft.Json.NullValueHandling.Ignore;
            });
        }

AddNewtonsoftJson方法启用JSON.NET序列化器,替代标准的ASP.NET Core序列化器。它有自己的配置类MvcNewtonsoftJsonOptions,设置了NullValueHandlinge值丢弃空值。

3.4 定义操作方法

        [HttpPatch("{id}")]
        public async Task<Supplier> PatchSupplier(long id,
            JsonPatchDocument<Supplier> supplierDocument)
        {
            Supplier supplier = await _context.Suppliers.FindAsync(id);
            if (supplier != null)
            {
                supplierDocument.ApplyTo(supplier);
                await _context.SaveChangesAsync();
            }
            return supplier;
        }

用HttpPatch修饰方法,通过JsonPatchDocument参数来处理JSON Patch文档。它有个ApplyTo方法,将每个操作应用于一个对象。
发送以下请求修改:
Invoke-RestMethod http://localhost:5000/api/suppliers/1 -Method Patch -ContentType "application/json" -Body '[{"op":"replace","path":"Name","value":"abc"}]'

4 理解内容的格式化

4.1 理解默认的内容策略

  • 如果操作方法返回一个字符串,则吧未修改的字符串返回客户端,响应的Content-Type头设置为text/plain。
  • 对于所有其他类型,包括int等其他简单类型,数据格式化为json,响应的Content-Type头设置为application/json。

添加ContentController类。

    [ApiController]
    [Route("api/[controller]")]
    public class ContentController : ControllerBase
    {
        private DataContext _dataContext;
        public ContentController(DataContext dataContext)
        {
            _dataContext = dataContext;
        }
        [HttpGet("string")]
        public string GetString()
            => "addffdsfdfdfd";

        [HttpGet("object")]
        public async Task<Product> GetObject()
        {
            return await _dataContext.Products.FirstAsync();
        }
    }

Invoke-WebRequest http://localhost:5000/api/content/string | select @{n='Content-Type';e={$_.Headers."Content-Type"}},Content
Invoke-WebRequest http://localhost:5000/api/content/object | select @{n='Content-Type';e={$_.Headers."Content-Type"}},Content

4.2 理解内容协商

(1)启用XML格式

要使内容协商生效,必须对应用程序进行配置,以便可以选择使用的格式。Json已经成为默认格式,但是MVC框架也可以支持将数据编码为Xml。
启用xml格式。

services.AddControllers().AddNewtonsoftJson().AddXmlSerializerFormatters(); 

xml序列化不能处理EFCore导航属性,因为它是通过接口定义的。修改GetObject使用可序列化的ProductBindingTarget对象

        [HttpGet("object")]
        public async Task<ProductBindingTarget> GetObject()
        {
            Product p = await _dataContext.Products.FirstAsync();
            return new ProductBindingTarget()
            {
                Name = p.Name,
                Price = p.Price,
                CategoryId = p.CategoryId,
                SupplierId = p.SupplierId
            };
        }

只有可用Json格式时别无选择,现在有了选择可以内容协商用application/xml输出。
Invoke-WebRequest http://localhost:5000/api/content/object -Headers @{Accept="application/xml"} | select @{n='Content-Type';e={$_.Headers."Content-Type"}},Content

(2)完全尊重Accept表头

如果Accept表头包含任何格式的/,mvc框架始终使用json格式。我们需要两个配置告诉mvc框架尊重客户端设置,默认情况下不发送json数据。

            services.Configure<MvcOptions>(opts => {
                opts.RespectBrowserAcceptHeader = true;
                opts.ReturnHttpNotAcceptable = true;
            });

设置MvcOptions对象属性,RespectBrowserAcceptHeader为true表示禁止在Accept包含/时回退到json,ReturnHttpNotAcceptable为true表示禁止在客户端请求不支持数据格式时回退到json。

4.3 指定操作结果格式

        [HttpGet("object")]
        [Produces("application/json")]
        public async Task<ProductBindingTarget> GetObject()

4.4 在URL中请求格式

通过使用FormatFilter属性修饰操作方法并确保操作方法的路由中有一个format段变量来启用该特性。

        [HttpGet("object/{format?}")]
        [FormatFilter]
        [Produces("application/json", "application/xml")]
        public async Task<ProductBindingTarget> GetObject()

可以在URl中设置请求格式,如:http://localhost:5000/api/content/object/xml、http://localhost:5000/api/content/object/json。

4.5 限制操作方法接收的格式

可以将Consumes属性应用于操作方法,以限制要处理的数据类型。

        [HttpPost]
        [Consumes("application/json")]
        public string SaveProductJson(ProductBindingTarget product)
        {
            return $"JSON: {product.Name}";
        }

        [HttpPost]
        [Consumes("application/xml")]
        public string SaveProductXml(ProductBindingTarget product)
        {
            return $"XML: {product.Name}";
        }

5 记录和探索Web服务

OpenAPI规范也称为Swagger,它提供描述Web服务。

5.1 解决操作冲突

OpenAPI发现过程要求对每个操作方法使用唯一HTTP方法和URL模式组合。该进程不支持Consumes属性,需要删除这些方法。

5.2 安装和配置Swashbuckle包

dotnet add package Swashbuckle.AspNetCore --version 5.5.0-rc2
在Startup中配置。

            services.AddSwaggerGen(options => {
                options.SwaggerDoc("v1",
                    new OpenApiInfo { Title = "WebApp", Version = "v1" });
            });
            app.UseSwagger();
            app.UseSwaggerUI(options => {
                options.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApp");
            });

在浏览器中访问:http://localhost:5000/swagger/v1/swagger.json,可以看到控制器的期望接收的数据详细和生成的响应范围。访问:http://localhost:5000/swagger/index.html,可以看到Web服务的OpenAPI描述。

5.3 微调API描述

(1)运行API分析器

在项目文件夹.csproj文件中启用分析器。

  <PropertyGroup>
    <IncludeOpenAPIAnalyzers>true</IncludeOpenAPIAnalyzers>
  </PropertyGroup>

分析器会检测到return NotFound();只返回一个状态码响应。

(2)声明操作方法结果类型

要修复检测到的问题,可以使用ProducesResponseType属性声明操作方法结果类型。

        [HttpGet("{id}")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public async Task<IActionResult> GetProduct(long id)

标签:Web,20,特性,id,Content,json,supplier,return,public
From: https://www.cnblogs.com/nullcodeworld/p/18154358

相关文章

  • MPV PLAYER播放器 快捷键  2024版本
    MPVPLAYER播放器快捷键 2024版本#MBTN_LEFT忽略#什么都不做#MBTN_LEFT_DBL循环全屏#切换全屏#MBTN_RIGHT循环暂停#切换暂停/播放模式#MBTN_BACK播放列表前一个#跳到前一个文件#MBTN_FORWARD播放列表next#跳到下一个文件#鼠标滚轮、触摸板或其他具有轴的输入设备#如果输......
  • 20231325 贾罗祁 实验三《Python程序设计》实验报告
    20231325贾罗祁2023-2024-2《Python程序设计》实验三报告课程:《Python程序设计》班级:2313姓名:贾罗祁学号:20231325实验教师:王志强实验日期:2024年4月17日必修/选修:公选课1.实验内容创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套......
  • ECMAScript(简称 ES)是一种由 Ecma 国际组织制定的脚本语言标准,用于定义脚本语言的语法
    ECMAScript(简称ES)是一种由Ecma国际组织制定的脚本语言标准,用于定义脚本语言的语法、类型、语义和其他核心特性。它的设计初衷是为了使不同的浏览器和开发者能够使用一致的语法和特性开发Web应用程序,从而提高跨平台和跨浏览器的互操作性。ECMAScript标准的制定由Ecma......
  • 挑战前端基础120题--JavaScript 中如何实现链式调用的函数?
    一.何为链式调用?链式调用是一种简化过程的编码方式,使代码看起来更加简洁~它允许你通过在方法调用之间返回对象本身,从而连续地调用多个方法;比较常见的链式调用:jQuery,Promise等,通过多次书写.或()操作来调用。二.实现的原理?每次执行完成后返回自己/新的自己,这样可以确保后续的......
  • [BJDCTF 2020]YDSneedGirlfriend
    [BJDCTF2020]YDSneedGirlfriendUAF|所谓UAF漏洞是指程序在运行时通过悬空指针(悬空指针是指仍然指向已被释放内存空间的指针)访问已经被释放的内存.bamuwe@bamuwe:~/YDSneedGirlfriend$lddgirlfriendlinux-vdso.so.1(0x00007ffd09fec000)/home/bamuwe/pw......
  • 2024-04-23---简单题---有效的字母异位词(哈希表)
    题目:思路:排序:复杂度较高。两个字符串进行排序,然后开始比较两个字符串是否相等哈希表:主要是一个hashmap记录第一个字符串所有字符出现的次数,然后遍历第二个字符串没找到一个就将次数减一。看最后所有的值是否为0.时间复杂度选第二种,简单题罢了。代码:排序classSolution......
  • 【专题】2023-2024年二手车市场消费需求洞察报告合集PDF分享(附原数据表)
    原文链接:https://tecdat.cn/?p=36021原文出处:拓端数据部落公众号2023年,乘用车二手车市场展现出了蓬勃的发展态势,交易量攀升至1478万辆,同比增长高达15%,创下了近五年的新纪录。在这一繁荣景象的背后,以旧换新政策的助力功不可没,它极大地激发了消费者的换购热情,为二手车市场注入了......
  • 20240423打卡
    第九周第一天第二天第三天第四天第五天第六天第七天所花时间9h4h代码量(行)727110博客量(篇)11知识点了解完成了地铁查询系统的App优化了地铁查询代码并通过验收......
  • 2024年4月23日
    今天我主要将结组作业的登录页面的后端逻辑写了一下代码如下:<script>exportdefault{name:"loginOne",data(){return{form:{id:'',password:''}}},methods:{register(){......
  • The 2022 ICPC Asia Xian Regional Contest
    The2022ICPCAsiaXianRegionalContestJ.StrangeSum题意:给定n个数,选定最多不超过两个数字的和的最大值思路:签到voidsolve(){lln;cin>>n;vector<ll>a(n+1);for(inti=1;i<=n;i++)cin>>a[i];llans=0;sort(a.begin()......