HttpClient.PatchAsJsonAsync - dotnet/runtime 项目贡献小记

TL;DR

迫于 PatchAsJsonAsync 方法缺失,我给 dotnet/runtime 项目贡献了相关的 API,可惜要到 .NET7 才能用上。

https://github.com/dotnet/runtime/pull/60672

正文

同事小张issue 收到了回复,希望他可以提供一个标准的 API Proposal 以供后续 review 使用。坐在隔壁的我得知此事之后,主动接过了这个锅([API Proposal]: HttpClient.PatchAsJsonAsync()),然后就有了这篇博文接下来的内容。

API Review 是线上直播的模式,有兴趣的可以去看一下,还是挺好玩的,issue 里有提到视频的地址。

HttpClient.PatchAsJsonAsync - dotnet/runtime 项目贡献小记

视频里有提到,这个 API 是从 json.net 相关的 API 迁移过来的,当时就没有 PATCH 方法的重载。显然 PATCH 方法没什么人用,这个 API 就惨遭 Overlooked(忽视) 了。

一个悲伤的故事,我的 Proposal 里 API 是直接复制粘贴然后替换的,里面有个语法错误,Review 的人也是复制粘贴的,幸好后来有人发现了(果然天下程序员都是一招 Ctrl + CV)。

接下来进行开发,其实也就是复制粘贴的事 = =。

首先在 GitHub fork dotnet/runtime 存储库,再克隆到本地。

我平时主要使用 Rider,因此 VS 里很多工作负载没装。在 VS Installer 里勾上 .NET 桌面开发,Python 开发和 C++ 桌面开发,根据提示重启电脑。

HttpClient.PatchAsJsonAsync - dotnet/runtime 项目贡献小记

一定要记得 关闭 Resharper,不然之后打开 VS 的时候就会这样:

HttpClient.PatchAsJsonAsync - dotnet/runtime 项目贡献小记

接下来根据官方给的步骤走就可以(https://github.com/dotnet/runtime/blob/main/docs/workflow/building/libraries/README.md)

打开终端,导航到项目文件夹下面,运行命令 build.cmd clr+libs -rc Release
如果不想看到 VS 里满屏的红色波浪线的话,一定要先做这一步。

这次我们需要修改的代码位于 System.Net.Http.Json 命名空间下,在对应文件夹里找到解决方案文件,用 VS 打开就可以。

可以看到里面的文件排布十分有规律,复制 Post 的文件然后批量改成 Patch。

HttpClient.PatchAsJsonAsync - dotnet/runtime 项目贡献小记

注意到一个问题,HttpClient.PatchAsync 在 .net46 和 .netstandrad 里是没有的,只能想办法兼容了(开发任务突然增加)。

HttpClient.PatchAsJsonAsync - dotnet/runtime 项目贡献小记

之前我是没有做过兼容多个 SDK 的项目的,只能先看看同项目下面其他方法是如何操作的,观察到 csproj 里有这样的代码:

HttpClient.PatchAsJsonAsync - dotnet/runtime 项目贡献小记

用 Condition 选择性编译了一些文件,那么这里就可以将 HttpClient.PatchAsync 反向迁移回去,搜索一下目前的实现,然后复制粘贴为 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 方法呢?)

修复编译错误之后,在 ref 里面添加方法声明(同样也是复制粘贴替换)。

接下来就是写测试,复制 POST 方法的测试然后改成 PATCH 就行了(CVH 大法好)。

然后提交 PR 就 ok 了,当然 PR review 过程也比较曲折,有兴趣的可以看一下开头 PR 里的 Conversation,对我多年不用的英语写作提出了巨大考验。

最近有很多博主都喜欢在最后放自己的微信公众号、打赏链接之类的。作为 N 年前迁移博客园博客系统到 .Net Core 的始作俑者(一系列 故障公告),大家多多使用博客园写博文就是对我最好的支持了 ╰(°▽°)╯。

另,有点想像 The Old New Thing 一样写一些博客园开发中遇到的好玩事情,不知道有没有人想看hhhh。(dudu 不要打我hhh)

上一篇:iOS学习笔记---c语言第九天


下一篇:iOS:Swift界面实例1, 简单界面