基于华为云官方 .NET SDK 调用 CDN API 刷新缓存

准备将园子的部分图片站切换到华为云 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;
posted @ 2021-11-15 14:40  dudu  阅读(707)  评论(1编辑  收藏  举报