准備將園子的部分圖片站切換到華為雲 CDN,切換前需要解決 CDN 緩存刷新問題。
華為雲 CDN 幫助文檔列出的 SDK 中沒有 .NET 版,原以為華為雲沒有提供官方 .NET SDK,於是在博問上提問看有沒有非官方的 .NET SDK —— 求華為雲CDN非官方.NET/C#版SDK。
在園友的回答中驚喜地知道,原來華為雲已經提供官方 .NET SDK —— Huawei Cloud .Net SDK,驚喜之余讓人失望的是沒有 CDN 部分的實現,慶幸的是認證鑒權部分已經在 HuaweiCloud.SDK.Core 中實現,自己寫代碼調用 CDN api 的工作量小了很多。
分享一下初步的實現代碼。
首先,創建 .NET 6 控制台程序並安裝 nuget 包 HuaweiCloud.SDK.Core
dotnet new console
dotnet add package HuaweiCloud.SDK.Core
接下來,創建 CdnClient 類並實現刷新緩存的異步方法 RefreshAsync
public class CdnClient : Client
{
public async Task<bool> RefreshAsync(params string[] urls)
{
SdkRequest request = HttpUtils.InitSdkRequest(
"v1.0/cdn/content/refresh-tasks",
"application/json;charset=UTF-8");
var data = new {
refresh_task = new
{
type = "file",
urls = urls
}
};
request.Body = JsonSerializer.Serialize(data);
var response = await DoHttpRequestAsync("POST", request);
if (response.IsSuccessStatusCode)
{
var resultType = new { refresh_task = "" }.GetType();
dynamic? result = await response.Content.ReadFromJsonAsync(resultType);
return int.TryParse(result?.refresh_task, out int taskId) && taskId > 0;
}
return false;
}
}
最后,Program 中調用 CdnClient 刷新緩存
using huawei_cloud_cdn;
using HuaweiCloud.SDK.Core;
using HuaweiCloud.SDK.Core.Auth;
using Microsoft.Extensions.Logging;
using static HuaweiCloud.SDK.Core.Client;
const string ak = "我的憑證 -> 訪問密鑰 -> Access Key Id";
const string sk = "我的憑證 -> 訪問密鑰 -> Secret Access Key";
const string endpoint = "https://cdn.myhuaweicloud.com/";
const string projectId = "我的憑證 -> API憑證 -> 項目ID";
var auth = new BasicCredentials(ak, sk, projectId);
var config = HttpConfig.GetDefaultConfig();
config.IgnoreSslVerification = true;
var cdnClient = new ClientBuilder<CdnClient>()
.WithCredential(auth)
.WithEndPoint(endpoint)
.WithHttpConfig(config)
.WithLogging(LogLevel.Information)
.Build();
var url = "https://common.cnblogs.com/logo.png";
var success = await cdnClient.RefreshAsync(url);
Console.WriteLine($"{(success ? "succeed": "fail")} to refresh {url}");
運行后成功刷新緩存。
$ dotnet run
info: System.Net.Http.HttpClient.SdkHttpClient.LogicalHandler[100]
Start processing HTTP request POST https://cdn.myhuaweicloud.com/v1.0/cdn/content/refresh-tasks
info: System.Net.Http.HttpClient.SdkHttpClient.ClientHandler[100]
Sending HTTP request POST https://cdn.myhuaweicloud.com/v1.0/cdn/content/refresh-tasks
info: System.Net.Http.HttpClient.SdkHttpClient.ClientHandler[101]
Received HTTP response after 2271.4836ms - OK
info: System.Net.Http.HttpClient.SdkHttpClient.LogicalHandler[101]
End processing HTTP request after 2301.9488ms - OK
succeed to refresh https://common.cnblogs.com/logo.png
實現過程中走了一個彎路,開始用下面的代碼反序列化響應的 json 內容
var result = await response.Content.ReadFromJsonAsync<dynamic>();
return int.TryParse(result?.refresh_task, out int taskId) && taskId > 0;
運行時報錯
'System.Text.Json.JsonElement' does not contain a definition for 'refresh_task'
原來是 System.Text.Json 不支持這樣反序列化匿名類型,反序列化的結果還是原來的 json 字符串。
后來改為下面的代碼解決了。
var resultType = new { refresh_task = "" }.GetType();
dynamic? result = await response.Content.ReadFromJsonAsync(resultType);
return int.TryParse(result?.refresh_task, out int taskId) && taskId > 0;