日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

如何在?ASP.NET?Core?Web?API?中處理?Patch?請求

瀏覽:72日期:2022-06-14 15:06:01
目錄一、概述二、將 Keys 保存在 Input Model 中三、定義 ModelBinderFactory 和 ModelBinder四、在 ASP.NET Core 項目中替換 ModelBinderFactory五、定義 AutoMapper 的 TypeConverter六、模型映射七、測試源碼參考資料一、概述

PUT 和 PATCH 方法用于更新現(xiàn)有資源。 它們之間的區(qū)別是,PUT 會替換整個資源,而 PATCH 僅指定更改。

在 ASP.NET Core Web API 中,由于 C# 是一種靜態(tài)語言(dynamic 在此不表),當我們定義了一個類型用于接收 HTTP Patch 請求參數(shù)的時候,在 Action 中無法直接從實例中得知客戶端提供了哪些參數(shù)。

比如定義一個輸入模型和數(shù)據(jù)庫實體:

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 形式接收參數(shù)的 Action:

[HttpPatch][Route('patch')]public ActionResult Patch([FromForm] PersonInput input){ // 測試代碼暫時將 AutoMapper 配置放在方法內(nèi)。 var config = new MapperConfiguration(cfg => {cfg.CreateMap<PersonInput, PersonEntity>()); }); var mapper = config.CreateMapper(); // entity 從數(shù)據(jù)庫讀取,這里僅演示。 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 而沒有其他參數(shù),從 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 和 ModelBinderpublic 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 項目中替換 ModelBinderFactoryvar 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 中已經(jīng)能獲取到請求的 Key 了。

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

PatchKeys 的作用是利用 AutoMapper。

五、定義 AutoMapper 的 TypeConverterpublic 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 創(chuàng)建 ModelBinder 而不是 ModelBinderProvider 以便于未來支持更多的輸入格式。 // 3. 目前還沒有支持多級結(jié)構(gòu)。 // 4. 測試代碼暫時將 AutoMapper 配置放在方法內(nèi)。 var config = new MapperConfiguration(cfg => {cfg.CreateMap<PersonInput, PersonEntity>().ConvertUsing(new PatchConverter<PersonEntity>()); }); var mapper = config.CreateMapper(); // PersonEntity 有 3 個屬性,客戶端如果提供的參數(shù)參數(shù)不足 3 個,在 Map 時未提供參數(shù)的屬性值不會被改變。 var entity = new PersonEntity {Name = '姓名',Age = 18,Gender = '如果客戶端沒有提供本參數(shù),那我的值不會被改變' }; 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 等。支持多級結(jié)構(gòu)。參考資料

GraphQL.NET

如何在 ASP.NET Core Web API 中處理 JSON Patch 請求

到此這篇關(guān)于在 ASP.NET Core Web API 中處理 Patch 請求的文章就介紹到這了,更多相關(guān)ASP.NET Core Web API 處理 Patch 請求內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標簽: ASP.NET
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
精品日本视频| 亚洲影视一区二区三区| 日韩高清三区| 国产毛片久久| 亚洲一区区二区| 日韩av一级| 六月婷婷一区| 精品国产美女a久久9999| 另类欧美日韩国产在线| 欧美福利专区| 爽爽淫人综合网网站| 老司机久久99久久精品播放免费| 亚洲三级观看| 老司机精品在线| 在线一区免费| 国产精品啊v在线| 国产精品日韩欧美一区| 国产精品白丝久久av网站| 麻豆免费精品视频| 国产综合精品一区| 国产精品久久久久久久久久白浆 | 青青国产91久久久久久| 免费成人性网站| 一区二区国产在线观看| 69堂精品视频在线播放| 国产精品免费精品自在线观看| 欧美日韩一区二区三区不卡视频| 在线日韩成人| 亚洲我射av| 午夜久久99| japanese国产精品| 久久久久久一区二区| 亚洲一区亚洲| 好吊日精品视频| 中文字幕色婷婷在线视频| 亚洲人亚洲人色久| 久久国产成人午夜av影院宅| 一区二区91| 激情91久久| 午夜欧美精品| 中文久久精品| 岛国av在线网站| 日韩av专区| 日韩av在线中文字幕| 久久裸体视频| 欧美男人天堂| www.九色在线| 亚洲国产不卡| 欧美日韩在线网站| 国产传媒av在线| 欧美日韩国产传媒| 日韩精品免费一区二区夜夜嗨| 国产精品亚洲欧美一级在线| 电影天堂国产精品| 免费高潮视频95在线观看网站| 久久福利影视| 日本成人在线网站| 亚洲少妇诱惑| 99精品网站| 久久国产中文字幕| 中文字幕成人| 国产成人精品一区二区三区视频| 国产一区精品福利| 精品不卡一区| 久久精品青草| 亚洲性色视频| 美美哒免费高清在线观看视频一区二区| 亚洲免费专区| 久久国产欧美日韩精品| 亚洲综合国产| 国产精品xvideos88| 91中文字幕精品永久在线| 精品三区视频| 在线视频免费在线观看一区二区| 快she精品国产999| 国产成人精品一区二区免费看京| 在线精品亚洲欧美日韩国产| 亚洲激情国产| 国产欧美日韩视频在线| 精品成av人一区二区三区| 在线日韩av| 亚洲制服一区| 蜜臀av在线播放一区二区三区| 国产精品片aa在线观看| 亚洲一区日韩| 国内精品亚洲| 美女国产精品| 神马午夜久久| 国产精品美女在线观看直播| 久久福利毛片| 欧美日韩精品一本二本三本| 日本精品黄色| 精品亚洲二区| 天堂av一区| 午夜欧美精品久久久久久久| 欧美午夜三级| 亚洲精品国产偷自在线观看| 日韩大片免费观看| 亚洲毛片在线免费| 亚洲午夜精品久久久久久app| 国产精品久久久久久久久久久久久久久 | 蜜臀av亚洲一区中文字幕| 国产欧美一区二区三区精品观看| 亚洲专区欧美专区| 亚洲国产成人二区| 99精品在线观看| 日韩精品久久久久久久软件91| 亚洲免费精品| 国产一区二区三区不卡av| 亚洲久草在线| 国产一区91| 日韩视频不卡| 99视频精品| 波多野结衣一区| 国产一区日韩一区| 欧美性感美女一区二区| 日本久久成人网| 99在线精品视频在线观看| 精品美女在线视频| 日韩在线不卡| 香蕉久久国产| 综合国产精品| 日韩激情中文字幕| 国产高清日韩| 在线精品福利| 综合国产在线| 国产欧美日韩影院| 精品中文在线| 91一区二区| 午夜一级久久| 日本少妇一区二区| 麻豆精品少妇| 久久精品123| 免费在线观看日韩欧美| 日韩精品一区二区三区免费视频| 国产精品成人自拍| 欧美日韩第一| 久久精品毛片| 黄色成人91| 99热免费精品| 亚洲欧美网站| 日韩一区二区三免费高清在线观看| 99国产精品久久久久久久成人热| 蜜桃tv一区二区三区| 91精品观看| 亚洲天堂av资源在线观看| 四虎精品一区二区免费| 国产情侣久久| 国产aⅴ精品一区二区四区| 精精国产xxxx视频在线播放| 99久久精品费精品国产| 日本天堂一区| 少妇久久久久| 视频一区中文字幕精品| 国产+成+人+亚洲欧洲在线| 蜜臀久久99精品久久一区二区| 欧美一区二区三区久久精品| 欧美精品羞羞答答| 不卡一二三区| 欧美韩一区二区| 日韩中文字幕无砖| 激情综合激情| 高清不卡亚洲| 欧美国产一级| 欧美一区二区三区免费看| 久久av一区二区三区| 亚洲二区精品| 国精品产品一区| 亚洲欧美专区| 亚洲成人va| 激情综合婷婷| 欧美aa一级| 999久久久国产精品| 精品网站aaa| 亚洲成人精品| 在线日韩一区| 国产毛片久久| 欧美日韩视频免费观看| 国产探花在线精品一区二区| 国产亚洲一级| 美女视频黄免费的久久| 91精品精品| 日韩高清中文字幕一区| 国产精品porn| 肉色欧美久久久久久久免费看| 国产亚洲一区在线| 麻豆精品少妇| 国产精品15p| 欧美在线黄色| 黑森林国产精品av| 91精品啪在线观看国产18| av一区在线| 丝袜av一区| 亚洲天堂av资源在线观看| 国产视频一区二区在线播放| 日本在线观看不卡视频| 欧美影院精品| 精品久久在线| 日韩.com| 不卡在线一区|