造成這個錯誤的原因是在使用 Senparc.Weixin SDK 或者 CO2NET 的擴充套件快取的時候,沒有對擴充套件快取策略進行註冊(啟用)。解決方案如下:
第一步:先升級到 Senparc.Weixin 的最新版本 v5.0.11 以上(依賴 CO2NET v0.1.11 以上):https://www.nuget.org/packages/Senparc.Weixin
第二步:檢查是否加入了一行程式碼:
.NET Framework:
在 global.asax.cs 檔案的 Application_Start() 方法中,加入程式碼(注意 using 兩個名稱空間:Senparc.CO2NET 和 Senparc.Weixin):
//... var isGLobalDebug = true;//設定全域性 Debug 狀態 var senparcSetting = SenparcSetting.BuildFromWebConfig(isGLobalDebug); var register = RegisterService.Start(senparcSetting).UseSenparcGlobal();//CO2NET全域性註冊,必須! var isWeixinDebug = true;//設定微信 Debug 狀態 var senparcWeixinSetting = SenparcWeixinSetting.BuildFromWebConfig(isWeixinDebug); register.UseSenparcWeixin(senparcWeixinSetting, senparcSetting);////微信全域性註冊,必須! //...
.NET Core:
在 startup.cs 中的 ConfigureServices() 和 Configure() 中分別加入程式碼(注意 using 兩個名稱空間:Senparc.CO2NET 和 Senparc.Weixin):
public void ConfigureServices(IServiceCollection services) { //... services.AddSenparcGlobalServices(Configuration)//Senparc.CO2NET 全域性註冊 .AddSenparcWeixinServices(Configuration);//Senparc.Weixin 註冊(如果使用Senparc.Weixin SDK則新增) //... }
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IOptions<SenparcSetting> senparcSetting, IOptions<SenparcWeixinSetting> senparcWeixinSetting) { //... IRegisterService register = RegisterService.Start(env, senparcSetting.Value).UseSenparcGlobal();// 啟動 CO2NET 全域性註冊,必須! register.UseSenparcWeixin(senparcWeixinSetting.Value, senparcSetting.Value);//微信全域性註冊,必須! //... }
只需要上述幾行程式碼即可。
進階
如果你的系統裡面自己擴充套件了 CO2NET 的快取策略(非 Senparc 官方的 LocalContainerCacheStrategy、RedisContainerCacheStrategy、MemcachedContainerCacheStrategy等),那麼上述的 .UseSenparcGlobal([第一個引數], [第二個引數]) 的第二個引數需要提供一個擴充套件的列表,以 .net core為例:
RegisterService.Start(env /* .net framework 沒有這個引數 */, senparcSetting).UseSenparcGlobal(false, GetExCacheStrategies);//必須
其中,GetExCacheStrategies 方法如下(以 .net core Demo 為例,.net framework 下面的 Demo 沒有 senparcWeixinSetting 引數):
/// <summary> /// 獲取擴充套件快取策略 /// </summary> /// <returns></returns> private IList<IDomainExtensionCacheStrategy> GetExCacheStrategies(SenparcWeixinSetting senparcWeixinSetting) { var exContainerCacheStrategies = new List<IDomainExtensionCacheStrategy>(); //注意:以下兩個 if 判斷僅作為演示,方便大家新增自定義的擴充套件快取策略, // 只要進行了 register.UseSenparcWeixin() 操作,Container 的快取策略下的 Local、Redis 和 Memcached 系統已經預設自動註冊,無需操作! #region 演示擴充套件快取註冊方法 //判斷Redis是否可用 var redisConfiguration = senparcWeixinSetting.Cache_Redis_Configuration; if ((!string.IsNullOrEmpty(redisConfiguration) && redisConfiguration != "Redis配置")) { exContainerCacheStrategies.Add(RedisContainerCacheStrategy.Instance); } //判斷Memcached是否可用 var memcachedConfiguration = senparcWeixinSetting.Cache_Memcached_Configuration; if ((!string.IsNullOrEmpty(memcachedConfiguration) && memcachedConfiguration != "Memcached配置")) { exContainerCacheStrategies.Add(MemcachedContainerCacheStrategy.Instance);//TODO:如果沒有進行配置會產生異常 } #endregion //擴充套件自定義的快取策略 return exContainerCacheStrategies; }
注意:上述程式碼以 Senparc.Weixin SDK 的擴充套件快取實現為例(用於 Container 的 Redis 和 Memecahed)實際上這兩個擴充套件快取再加上 LocalContainerCacheStrategy 已經在執行 register.UseSenparcWeixin() 的時候自動註冊,無需多此一舉。
當然,這樣有時候還是會稍顯麻煩,所以我們又提供了一個自動掃描所有的擴充套件快取並註冊的方法,完全由系統自動完成:
RegisterService.Start(senparcSetting).UseSenparcGlobal(true, null);//必須
注意:當地一個引數為 true 時,雖然省去了指定快取的程式碼,但是全域性的掃描需要消耗一定的時間,會導致系統啟動時間增加。粗略地測試,每個程式集(可近似理解為dll)會延長8毫秒左右的啟動時間。
PS:
Senparc.Weixin 預設提供了三種 Container 的擴充套件快取策略:
- LocalContainerCacheStrategy
- RedisContainerCacheStrategy
- MemcachedContainerCacheStrategy
您也可以編寫自己的擴充套件快取策略。