DotNet实现简单微信SDK
概述
上一篇文章C#实现微信扫码登录(绕过微信开发平台) - ihuadz 提到封装微信接口,本篇文章将从以下方面介绍如何使用C#实现简单的微信SDK。
仓库地址:https://github.com/ihuadz/QI.WxSdk.git
核心类库介绍
WebApiClient 是一个集高性能高可扩展性于一体的声明式http客户端库,具体使用方法可以查看一下官方文档
其他的都是使用dotnet提供的类库
配置
配置文件长这样,可配置多个小程序
1 2 3 4 5 6 7 8 9 10
| WeixinSetting: App: - AppId: xxxxxxxxxxxxxx AppSecret: xxxxxxxxxxxxxxxxxxxxxxx Name: xxxxxxxxxxxxxxx - AppId: xxxxxxxxxxxxxx AppSecret: xxxxxxxxxxxxxxxxxxxxxxx Name: xxxxxxxxxxxxxxx
|
具体实现
封装代码太多,文章内就放出核心代码,全部sdk查看概述。
1 2 3 4 5 6 7 8
|
[JsonNetReturn(EnsureMatchAcceptContentType = false)] public interface IWxApiBase { }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| [HttpHost("https://api.weixin.qq.com/cgi-bin/")] public interface IWxTokenApi : IWxApiBase { [HttpGet("token")] Task<TokenApiResult> GetAsync([Required] string appId, [Required] string secret, string grant_type = "client_credential");
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
protected virtual void CheckAppSetting() { if (CurApp == null) throw new WxException("应用配置不能空"); if (string.IsNullOrEmpty(CurApp.AppId)) throw new WxException("应用AppId能空"); if (string.IsNullOrEmpty(CurApp.AppSecret)) throw new WxException("应用AppSecret能空"); }
public virtual async Task<string> GetAccessTokenAsync() { CheckAppSetting();
string token = await GetAccessTokenFromCacheAsync(); if (!string.IsNullOrEmpty(token)) return token;
IWxTokenApi tokenApi = GetService<IWxTokenApi>(); TokenApiResult result = await tokenApi.GetAsync(CurApp.AppId, CurApp.AppSecret);
await SetAccessTokenToCacheAsync(result.AccessToken, result.Expires);
return result.AccessToken; }
|
- 最主要的是这一步,使用WebApiClient过滤器将access_token设置到每次请求微信的url中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
public class AccessTokenApiFilter : ApiFilterAttribute { public override async Task OnRequestAsync(ApiRequestContext context) { var tokenManager = context.HttpContext.ServiceProvider.GetRequiredService<ITokenManager>(); string accessToken = await tokenManager.GetAccessTokenAsync(); context.HttpContext.RequestMessage.AddUrlQuery("access_token", accessToken); }
public override Task OnResponseAsync(ApiResponseContext context) { if(context.Result is ApiResultBase apiResult && apiResult!=null) { if (apiResult.IsAccessTokenInvalid) { var tokenManager = context.HttpContext.ServiceProvider.GetRequiredService<ITokenManager>(); tokenManager.ClearAccessTokenAsync(); } }
return Task.CompletedTask; } }
|
以上次文章中使用到的请求短链为例,实现请求微信端。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
public interface IWxMpUrllinkApi : IWxApiWithAccessTokenFilter { [HttpPost("https://api.weixin.qq.com/wxa/generate_urllink")] ITask<GenerateUrlLinkResult> GenerateUrllinkAsync([JsonNetContent] GenerateUrlLinkInput input); }
|
IWxApiWithAccessTokenFilter
1 2 3 4 5 6 7 8
|
[JsonNetReturn(EnsureMatchAcceptContentType = false)] [AccessTokenApiFilter] public interface IWxApiWithAccessTokenFilter { }
|
然后就是WxMpApiService,这里就只放短链相关
1 2 3 4 5 6 7 8 9 10
|
public class WxMpApiService : WxApiServiceBase { public IWxMpUrllinkApi IUrllinkApi => GetService<IWxMpUrllinkApi>(); }
|
WxApiServiceBase 接口聚合服务 基类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
public class WxApiServiceBase { public WxApiServiceBase(ITokenManager tokenManager) { TokenManager = tokenManager; }
public virtual ITokenManager TokenManager { get; }
protected virtual T GetService<T>() { return TokenManager.GetService<T>(); }
public virtual void SetCurApp(WxAppSetting wxApp) { TokenManager.SetCurApp(wxApp); }
public virtual void SetCurApp(string appId) { TokenManager.SetCurApp(appId); }
public virtual string GetCurAppId() { return TokenManager?.GetCurAppId() ?? string.Empty; }
public virtual WxAppSetting GetCurApp() { return TokenManager.GetCurApp(); } }
|
至于ITokenManager,自己设计一下就好,都是读取配置和缓存AccessToken的一些操作,也可以查看源码概述。
最后就是如何使用了。添加一个扩展类,将封装好的Api注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
public static IServiceCollection AddWxSdkAll(this IServiceCollection services) { services.AddWxSdkApiAndServices(); services.AddWxSdkTokenManager();
return services; }
public static IServiceCollection AddWxSdkTokenManager(this IServiceCollection services) { services.AddScoped<ITokenManager, TokenManager>();
return services; }
public static IServiceCollection AddWxSdkApiAndServices(this IServiceCollection services) { services .AddWebApiClient() .UseJsonFirstApiActionDescriptor();
services.AddSingleton<WxConfig>();
services.AddHttpApi<IWxTokenApi>();
services.AddScoped<WxPaApiService>();
services.AddHttpApi<IWxMpUrllinkApi>();
services.AddScoped<WxMpApiService>();
return services; }
|
如何使用
在你的应用中添加注册
1 2
| services.AddWxSdkAll();
|
在service里注入后调用
1 2 3 4 5 6 7 8
| var urlResult = await _wxMpService.IUrllinkApi.GenerateUrllinkAsync(new GenerateUrlLinkInput() { Path = path, Query = query, EnvironmentVersion = environmentVersion, ExpireTimestamp = DateTime.Now.AddMinutes(10).ConvertToTimeStamp() });
|