iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >在 ASP.NET Core Web API 中处理Patch请求的方法
  • 788
分享到

在 ASP.NET Core Web API 中处理Patch请求的方法

2023-07-06 14:07:39 788人浏览 独家记忆
摘要

今天小编给大家分享的是在 asp.net Core WEB api 中处理Patch请求的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收

今天小编给大家分享的是在 asp.net Core WEB api 中处理Patch请求的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。

一、概述

PUT 和 PATCH 方法用于更新现有资源。 它们之间的区别是,PUT 会替换整个资源,而 PATCH 仅指定更改。

ASP.net core Web API 中,由于 C# 是一种静态语言(dynamic 在此不表),当我们定义了一个类型用于接收 Http Patch 请求参数的时候,在 Action 中无法直接从实例中得知客户端提供了哪些参数。

比如定义一个输入模型和数据库实体:

public class PersonInput{    public string? Name { get; set; }    public int? Age { get; set; }    public string? Gender { get; set; }}public class PersonEntity{    public string Name { get; set; }    public int Age { get; set; }    public string Gender { get; set; }}

再定义一个以 FromFORM 形式接收参数的 Action:

[HttpPatch][Route("patch")]public ActionResult Patch([FromForm] PersonInput input){    // 测试代码暂时将 AutoMapper 配置放在方法内。    var config = new MapperConfiguration(cfg =>    {        cfg.CreateMap<PersonInput, PersonEntity>());    });    var mapper = config.CreateMapper();    // entity 从数据库读取,这里仅演示。    var entity = new PersonEntity    {        Name = "姓名", // 可能会被改变        Age = 18, // 可能会被改变        Gender = "我可能会被改变",    };    // 如果客户端只输入 Name 字段,entity 的 Age 和 Gender 将不能被正确映射或被置为 null。    mapper.Map(input, entity);    return Ok();}
curl --location --request PATCH 'http://localhost:5094/test/patch' \--form 'Name="foo"'

如果客户端只提供了 Name 而没有其他参数,从 HttpContext.Request.Form.Keys 可以得知这一点。如果不使用 AutoMapper,那么接下来是丑陋的判断:

var keys = _httpContextAccessor.HttpContext.Request.Form.Keys;if(keys.Contains("Name")){    // 更新 Name(这里忽略合法性判断)    entity.Name = input.Name!;}if (keys.Contains("Age")){    // 更新 Age(这里忽略合法性判断)    entity.Age = input.Age!;}// ...

本文提供一种方式来简化这个步骤。

二、将 Keys 保存在 Input Model 中

定义一个名为 PatchInput 的类:

public abstract class PatchInput{    [BindNever]    public ICollection<string>? PatchKeys { get; set; }}

PatchKeys 属性不由客户端提供,不参与默认绑定。

PersonInput 继承自 PatchInput:

public class PersonInput : PatchInput{    public string? Name { get; set; }    public int? Age { get; set; }    public string? Gender { get; set; }}

三、定义 ModelBinderFactory 和 ModelBinder

public class PatchModelBinder : IModelBinder{    private readonly IModelBinder _internalModelBinder;    public PatchModelBinder(IModelBinder internalModelBinder)    {        _internalModelBinder = internalModelBinder;    }    public async Task BindModelAsync(ModelBindinGContext bindingContext)    {        await _internalModelBinder.BindModelAsync(bindingContext);        if (bindingContext.Model is PatchInput model)        {            // 将 Form 中的 Keys 保存在 PatchKeys 中            model.PatchKeys = bindingContext.HttpContext.Request.Form.Keys;        }    }}
public class PatchModelBinderFactory : IModelBinderFactory{    private ModelBinderFactory _modelBinderFactory;    public PatchModelBinderFactory(        IModelMetadataProvider metadataProvider,        IOptions<mvcOptions> options,        IServiceProvider serviceProvider)    {        _modelBinderFactory = new ModelBinderFactory(metadataProvider, options, serviceProvider);    }    public IModelBinder CreateBinder(ModelBinderFactoryContext context)    {        var modelBinder = _modelBinderFactory.CreateBinder(context);        // ComplexObjectModelBinder 是 internal 类        if (typeof(PatchInput).IsAssignableFrom(context.Metadata.ModelType)            && modelBinder.GetType().ToString().EndsWith("ComplexObjectModelBinder"))        {            modelBinder = new PatchModelBinder(modelBinder);        }        return modelBinder;    }}

四、在 ASP.net core 项目中替换 ModelBinderFactory

var builder = WebApplication.CreateBuilder(args);// Add services to the container.builder.Services.AddPatchMapper();

AddPatchMapper 是一个简单的扩展方法:

public static class PatchMapperExtensions{    public static IServiceCollection AddPatchMapper(this IServiceCollection services)    {        services.Replace(ServiceDescriptor.Singleton<IModelBinderFactory, PatchModelBinderFactory>());        return services;    }}

到目前为止,在 Action 中已经能获取到请求的 Key 了。

[HttpPatch][Route("patch")]public ActionResult Patch([FromForm] PersonInput input){    // 不需要手工给 input.PatchKeys 赋值。    return Ok();}

PatchKeys 的作用是利用 AutoMapper。

五、定义 AutoMapper 的 TypeConverter

public class PatchConverter<T> : ITypeConverter<PatchInput, T> where T : new(){    /// <inheritdoc />    public T Convert(PatchInput source, T destination, ResolutionContext context)    {        destination ??= new T();        var sourceType = source.GetType();        var destinationType = typeof(T);        foreach (var key in source.PatchKeys ?? Enumerable.Empty<string>())        {            var sourcePropertyInfo = sourceType.GetProperty(key, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);            if (sourcePropertyInfo != null)            {                var destinationPropertyInfo = destinationType.GetProperty(key, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);                if (destinationPropertyInfo != null)                {                    var sourceValue = sourcePropertyInfo.GetValue(source);                    destinationPropertyInfo.SetValue(destination, sourceValue);                }            }        }        return destination;    }}

上述代码可用其他手段来代替反射

六、模型映射

[HttpPatch][Route("patch")]public ActionResult Patch([FromForm] PersonInput input){    // 1. 目前仅支持 `FromForm`,即 `x-www-form_urlencoded` 和 `form-data`;暂不支持 `FromBody` 如 `raw` 等。    // 2. 使用 ModelBinderFractory 创建 ModelBinder 而不是 ModelBinderProvider 以便于未来支持更多的输入格式。    // 3. 目前还没有支持多级结构。    // 4. 测试代码暂时将 AutoMapper 配置放在方法内。    var config = new MapperConfiguration(cfg =>    {        cfg.CreateMap<PersonInput, PersonEntity>().ConvertUsing(new PatchConverter<PersonEntity>());    });    var mapper = config.CreateMapper();    // PersonEntity 有 3 个属性,客户端如果提供的参数参数不足 3 个,在 Map 时未提供参数的属性值不会被改变。    var entity = new PersonEntity    {        Name = "姓名",        Age = 18,        Gender = "如果客户端没有提供本参数,那我的值不会被改变"    };    mapper.Map(input, entity);    return Ok();}

七、测试

curl --location --request PATCH 'http://localhost:5094/test/patch' \--form 'Name="foo"'

curl --location --request PATCH 'http://localhost:5094/test/patch' \--header 'Content-Type: application/x-www-form-urlencoded' \--data-urlencode 'Name=foo'

源码

Tubumu.PatchMapper

  • 支持 FromForm,即 x-www-form_urlencoded 和 form-data

  • 支持 FromBody 如 raw 等。

  • 支持多级结构。

参考资料

GraphQL.net

如何在 ASP.Net Core Web API 中处理 JSON Patch 请求

关于在 ASP.NET Core Web API 中处理Patch请求的方法就分享到这里了,希望以上内容可以对大家有一定的参考价值,可以学以致用。如果喜欢本篇文章,不妨把它分享出去让更多的人看到。

--结束END--

本文标题: 在 ASP.NET Core Web API 中处理Patch请求的方法

本文链接: https://www.lsjlt.com/news/358526.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 在 ASP.NET Core Web API 中处理Patch请求的方法
    今天小编给大家分享的是在 ASP.NET Core Web API 中处理Patch请求的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收...
    99+
    2023-07-06
  • 如何在 ASP.NET Core Web API 中处理 Patch 请求
    目录一、概述二、将 Keys 保存在 Input Model 中三、定义 ModelBinderFactory 和 ModelBinder四、在 ASP.NET Core 项目中替换...
    99+
    2023-05-20
    ASP.NET Core Web API 处理 Patch 请求 ASP.NET Core  Patch 请求
  • ASP.NET Core中怎么利用 Razor处理Ajax请求
    这篇文章将为大家详细讲解有关ASP.NET Core中怎么利用 Razor处理Ajax请求,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。RazorRazor Pages是ASP.NET Co...
    99+
    2023-06-19
  • SpringBoot配置Controller实现Web请求处理的方法
    今天小编给大家分享的是SpringBoot配置Controller实现Web请求处理的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。Controller处理请求由于 在建立 Sp...
    99+
    2023-08-03
  • ASP.NET Core中Razor页面的Handlers处理方法详解
    简介 在前一篇文章中,我们讨论了Razor页面。今天我们来谈谈处理方法(Handlers)。 我们知道可以将代码和模型放在 .cshtml 文件里面或与 ...
    99+
    2024-04-02
  • 如何在C++中处理Web请求和响应?
    使用 cpproxy 库处理 web 请求和响应的步骤如下:安装 cpproxy 库。创建 http 服务器对象并设置端口和地址。为特定请求路径设置处理程序。在处理程序中,创建响应对象,...
    99+
    2024-05-11
    web请求 web响应 c++
  • PHP中POST请求参数的处理方法
    PHP中POST请求参数的处理方法 在PHP中,POST请求是一种常见的数据传递方式,通常用于向服务器提交表单数据或其他需要保密的数据。处理POST请求参数是开发者常见的需求,在下面的...
    99+
    2024-04-02
  • SpringMVCajax请求的处理方法介绍
    目录准备工作一、@RequestBody二、@RequestBody获取json格式的请求参数三、@ResponseBody四、@ResponseBody响应浏览器json数据五、@...
    99+
    2022-11-13
    SpringMVC ajax请求 SpringMVC ajax
  • 如何在PHP中优化API请求的打包和并发处理?
    随着现代Web应用程序的快速发展,前后端分离的趋势越来越明显,API成为了Web应用程序中不可或缺的一部分。在PHP中,开发者需要面对的一个重要问题是如何优化API请求的打包和并发处理,以提高应用程序的性能和响应速度。本文将介绍一些PHP中...
    99+
    2023-10-26
    打包 并发 api
  • springboot对压缩请求的处理方法
    目录springboot对压缩请求的处理一、Tomcat设置压缩原理二、银联报文压缩补充:java springbooot使用gzip压缩字符串springboot对压缩请求的处理 ...
    99+
    2023-05-18
    springboot压缩请求 springboot请求
  • Vuex中actions优雅处理接口请求的方法
    目录前言文件结构前言 在项目开发中,如果使用到了 vuex,通常我会将所有的接口请求单独用一个文件管理,而业务逻辑写在 actions 中,一方面方便统一管理项目中的所有请求,其次代...
    99+
    2022-11-16
    Vuex actions接口请求 Vuex接口请求 Vuex actions请求
  • php处理post请求的方法是什么
    在PHP中处理POST请求的方法是使用$_POST超全局变量来获取POST请求的数据。$_POST是一个关联数组,它包含了所有的PO...
    99+
    2023-10-10
    PHP
  • 聊聊Golang在处理请求方面的优势
    Golang(或Go)作为一种新型的编程语言,因其高效、安全、并行处理能力而被许多大型公司广泛采用。在处理请求方面,Golang 的优势在于其高效、稳定性强、易于编写和维护,以下是详细解释。高效性:首先就是Golang 在处理请求方面的高效...
    99+
    2023-05-14
  • django异步请求处理的方法是什么
    Django中的异步请求处理可以通过以下几种方法实现:1. 使用Django的内置异步任务处理机制:Django提供了一个名为`as...
    99+
    2023-09-26
    Django
  • 浏览器请求流程和PHP对请求的处理方法是什么
    这篇“浏览器请求流程和PHP对请求的处理方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“浏览器请求流程和PHP对请求...
    99+
    2023-07-05
  • PHP中如何实现API请求的打包和并发处理?
    在现代Web应用程序中,调用API是非常常见的任务。API请求通常需要与第三方服务通信,这可能会导致应用程序的性能问题。这时候,我们就需要考虑如何优化API请求的处理方式。在本篇文章中,我们将讨论如何使用PHP实现API请求的打包和并发处...
    99+
    2023-10-26
    打包 并发 api
  • java处理高并发请求的方法是什么
    Java处理高并发请求的方法有很多种,以下是一些常用的方法: 使用线程池:可以使用Java中的线程池技术来管理并发请求。通过创建...
    99+
    2023-10-25
    java
  • go中的http请求日志处理方法,你掌握了吗?
    Go语言中的HTTP请求日志处理方法,是一项非常重要的技能。对于一个Web开发人员来说,HTTP请求日志是了解用户行为、发现系统问题、优化性能的重要工具。在Go语言中,我们可以通过内置的log包或第三方日志库来实现HTTP请求日志的处理。本...
    99+
    2023-08-04
    http 面试 日志
  • SpringBoot常见get/post请求参数处理的方法
    这篇文章主要介绍了SpringBoot常见get/post请求参数处理的方法的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇SpringBoot常见get/post请求参数处理的方法文章都会有所收获,下面我们一起...
    99+
    2023-06-29
  • 你知道PHP中如何同时处理并发的API请求吗?
    PHP是一种广泛使用的编程语言,其在Web开发中的应用广泛,特别是在处理API请求方面。但是,PHP在处理大量并发请求时会遇到一些问题。在本文中,我们将探讨如何在PHP中同时处理并发的API请求。 在PHP中,有几种方法可以同时处理并发的A...
    99+
    2023-10-26
    打包 并发 api
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作