HttpClient.PatchAsJsonAsync - dotnet/runtime 项目贡献小记
TL;DR
迫于 PatchAsJsonAsync 方法缺失,我給 dotnet/runtime 項(xiàng)目貢獻(xiàn)了相關(guān)的 API,可惜要到 .NET7 才能用上。
https://github.com/dotnet/runtime/pull/60672
正文
同事小陳 的 issue 收到了回復(fù),希望他可以提供一個(gè)標(biāo)準(zhǔn)的 API Proposal 以供后續(xù) review 使用。坐在隔壁的我得知此事之后,主動(dòng)接過(guò)了這個(gè)鍋([API Proposal]: HttpClient.PatchAsJsonAsync()),然后就有了這篇博文接下來(lái)的內(nèi)容。
API Review 是線(xiàn)上直播的模式,有興趣的可以去看一下,還是挺好玩的,issue 里有提到視頻的地址。
視頻里有提到,這個(gè) API 是從 json.net 相關(guān)的 API 遷移過(guò)來(lái)的,當(dāng)時(shí)就沒(méi)有 PATCH 方法的重載。顯然 PATCH 方法沒(méi)什么人用,這個(gè) API 就慘遭 Overlooked(忽視) 了。
一個(gè)悲傷的故事,我的 Proposal 里 API 是直接復(fù)制粘貼然后替換的,里面有個(gè)語(yǔ)法錯(cuò)誤,Review 的人也是復(fù)制粘貼的,幸好后來(lái)有人發(fā)現(xiàn)了(果然天下程序員都是一招 Ctrl + CV)。
接下來(lái)進(jìn)行開(kāi)發(fā),其實(shí)也就是復(fù)制粘貼的事 = =。
首先在 GitHub fork dotnet/runtime 存儲(chǔ)庫(kù),再克隆到本地。
我平時(shí)主要使用 Rider,因此 VS 里很多工作負(fù)載沒(méi)裝。在 VS Installer 里勾上 .NET 桌面開(kāi)發(fā),Python 開(kāi)發(fā)和 C++ 桌面開(kāi)發(fā),根據(jù)提示重啟電腦。
一定要記得 關(guān)閉 Resharper,不然之后打開(kāi) VS 的時(shí)候就會(huì)這樣:
接下來(lái)根據(jù)官方給的步驟走就可以(https://github.com/dotnet/runtime/blob/main/docs/workflow/building/libraries/README.md)
打開(kāi)終端,導(dǎo)航到項(xiàng)目文件夾下面,運(yùn)行命令 build.cmd clr+libs -rc Release。
如果不想看到 VS 里滿(mǎn)屏的紅色波浪線(xiàn)的話(huà),一定要先做這一步。
這次我們需要修改的代碼位于 System.Net.Http.Json 命名空間下,在對(duì)應(yīng)文件夾里找到解決方案文件,用 VS 打開(kāi)就可以。
可以看到里面的文件排布十分有規(guī)律,復(fù)制 Post 的文件然后批量改成 Patch。
注意到一個(gè)問(wèn)題,HttpClient.PatchAsync 在 .net46 和 .netstandrad 里是沒(méi)有的,只能想辦法兼容了(開(kāi)發(fā)任務(wù)突然增加)。
之前我是沒(méi)有做過(guò)兼容多個(gè) SDK 的項(xiàng)目的,只能先看看同項(xiàng)目下面其他方法是如何操作的,觀察到 csproj 里有這樣的代碼:
用 Condition 選擇性編譯了一些文件,那么這里就可以將 HttpClient.PatchAsync 反向遷移回去,搜索一下目前的實(shí)現(xiàn),然后復(fù)制粘貼為 HttpClientJsonExtensions.netstandard.cs。
private static Task<HttpResponseMessage> PatchAsync(this HttpClient client, string? requestUri, HttpContent content, CancellationToken cancellationToken)
{
Uri? uri = string.IsNullOrEmpty(requestUri) ? null : new Uri(requestUri, UriKind.RelativeOrAbsolute);
return client.PatchAsync(uri, content, cancellationToken);
}
private static Task<HttpResponseMessage> PatchAsync(this HttpClient client, Uri? requestUri, HttpContent content, CancellationToken cancellationToken)
{
// HttpClient.PatchAsync is not available in .NET standard and NET462
HttpRequestMessage request = new HttpRequestMessage(HttpPatch, requestUri) { Content = content };
return client.SendAsync(request, cancellationToken);
}
(突然想到,如果我聲明為 public 是不是順便就給 .netstandard2.0 提供了 PatchAsync 方法呢?)
修復(fù)編譯錯(cuò)誤之后,在 ref 里面添加方法聲明(同樣也是復(fù)制粘貼替換)。
接下來(lái)就是寫(xiě)測(cè)試,復(fù)制 POST 方法的測(cè)試然后改成 PATCH 就行了(CVH 大法好)。
然后提交 PR 就 ok 了,當(dāng)然 PR review 過(guò)程也比較曲折,有興趣的可以看一下開(kāi)頭 PR 里的 Conversation,對(duì)我多年不用的英語(yǔ)寫(xiě)作提出了巨大考驗(yàn)。
最近有很多博主都喜歡在最后放自己的微信公眾號(hào)、打賞鏈接之類(lèi)的。作為 N 年前遷移博客園博客系統(tǒng)到 .Net Core 的始作俑者(一系列 故障公告),大家多多使用博客園寫(xiě)博文就是對(duì)我最好的支持了 ╰(°▽°)╯。
另,有點(diǎn)想像 The Old New Thing 一樣寫(xiě)一些博客園開(kāi)發(fā)中遇到的好玩事情,不知道有沒(méi)有人想看hhhh。(dudu 不要打我hhh)
總結(jié)
以上是生活随笔為你收集整理的HttpClient.PatchAsJsonAsync - dotnet/runtime 项目贡献小记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 可能是流水调度问题的证明
- 下一篇: 入门篇-其之八-常用类的简单使用