#region Apache License Version 2.0 /*---------------------------------------------------------------- Copyright 2019 Jeffrey Su & Suzhou Senparc Network Technology Co.,Ltd. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Detail: https://github.com/JeffreySu/WeiXinMPSDK/blob/master/license.md ----------------------------------------------------------------*/ #endregion Apache License Version 2.0 /*---------------------------------------------------------------- Copyright (C) 2019 Senparc 文件名:ApiHandlerWapperBase.cs 文件功能描述:提供ApiHandlerWapper的公共基础方法 创建标识:Senparc - 20170702 修改标识:Senparc - 201700704 修改描述:优化TryCommonApiBaseAsync方法 修改标识:Senparc - 20170730 修改描述:v4.13.5 完善AppId未注册提示 修改标识:Senparc - 20181027 修改描述:v6.1.10 改进 TryCommonApiBase 方法 ----------------------------------------------------------------*/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Senparc.Weixin.Entities; using Senparc.Weixin.Exceptions; using Senparc.Weixin.Utilities.WeixinUtility; namespace Senparc.Weixin.CommonAPIs.ApiHandlerWapper { /// /// 所有子模块ApiHandlerWapper方法调用的基础方法 /// public class ApiHandlerWapperBase { #region 同步方法 /// /// TryCommonApi 方法的基类 /// /// /// 平台类型,PlatformType枚举 /// AccessTokenContainer中的GetFirstOrDefaultAppId()方法 /// AccessTokenContainer中的bool CheckRegistered(appId,getNew)方法 /// AccessTokenContainer中的AccessTokenResult GetAccessTokenResult(appId)方法 /// "ReturnCode.获取access_token时AppSecret错误或者access_token无效"枚举的值 /// /// /// /// public static T TryCommonApiBase( PlatformType platformType, Func accessTokenContainer_GetFirstOrDefaultAppIdFunc, Func accessTokenContainer_CheckRegisteredFunc, Func accessTokenContainer_GetAccessTokenResultFunc, int invalidCredentialValue, Func fun, string accessTokenOrAppId = null, bool retryIfFaild = true) where T : BaseJsonResult { //ApiHandlerWapperFactory.ApiHandlerWapperFactoryCollection["s"] = ()=> new Senparc.Weixin.MP.AdvancedAPIs.User.UserInfoJson(); //var platform = ApiHandlerWapperFactory.CurrentPlatform;//当前平台 /* * 对于企业微信来说,AppId = key = CorpId+CorpSecret */ string appId = null; string accessToken = null; if (accessTokenOrAppId == null) { appId = accessTokenContainer_GetFirstOrDefaultAppIdFunc != null ? accessTokenContainer_GetFirstOrDefaultAppIdFunc() : null;// AccessTokenContainer.GetFirstOrDefaultAppId(); if (appId == null) { throw new UnRegisterAppIdException(null, "尚无已经注册的AppId,请先使用AccessTokenContainer.Register完成注册(全局执行一次即可)!模块:" + platformType); } } else if (ApiUtility.IsAppId(accessTokenOrAppId, platformType)) { //if (!AccessTokenContainer.CheckRegistered(accessTokenOrAppId)) if (!accessTokenContainer_CheckRegisteredFunc(accessTokenOrAppId)) { throw new UnRegisterAppIdException(accessTokenOrAppId, string.Format("此appId({0})尚未注册,请先使用AccessTokenContainer.Register完成注册(全局执行一次即可)!模块:" + platformType, accessTokenOrAppId)); } appId = accessTokenOrAppId; } else { accessToken = accessTokenOrAppId;//accessToken } T result = null; try { if (accessToken == null) { var accessTokenResult = accessTokenContainer_GetAccessTokenResultFunc(appId, false); //AccessTokenContainer.GetAccessTokenResult(appId, false); accessToken = accessTokenResult.access_token; } result = fun(accessToken); } catch (ErrorJsonResultException ex) { if (retryIfFaild && appId != null //如果 appId 为 null,已经没有重试的意义(直接提供的 AccessToken 是错误的) //&& ex.JsonResult.errcode == ReturnCode.获取access_token时AppSecret错误或者access_token无效) && (int)ex.JsonResult.errcode == invalidCredentialValue) { //尝试重新验证 var accessTokenResult = accessTokenContainer_GetAccessTokenResultFunc(appId, true);//AccessTokenContainer.GetAccessTokenResult(appId, true); //强制获取并刷新最新的AccessToken accessToken = accessTokenResult.access_token; result = TryCommonApiBase(platformType, accessTokenContainer_GetFirstOrDefaultAppIdFunc, accessTokenContainer_CheckRegisteredFunc, accessTokenContainer_GetAccessTokenResultFunc, invalidCredentialValue, fun, accessToken, false); } else { ex.AccessTokenOrAppId = accessTokenOrAppId; throw; } } catch (WeixinException ex) { ex.AccessTokenOrAppId = accessTokenOrAppId; throw; } return result; } #endregion #if !NET35 && !NET40 #region 异步方法 /// /// TryCommonApi 方法的基类 /// /// /// 平台类型,PlatformType枚举 /// AccessTokenContainer中的GetFirstOrDefaultAppId()方法 /// AccessTokenContainer中的bool CheckRegistered(appId,getNew)方法 /// AccessTokenContainer中的AccessTokenResult GetAccessTokenResultAsync(appId)方法(异步方法) /// "ReturnCode.获取access_token时AppSecret错误或者access_token无效"枚举的值 /// /// /// /// public static async Task TryCommonApiBaseAsync( PlatformType platformType, Func accessTokenContainer_GetFirstOrDefaultAppIdFunc, Func accessTokenContainer_CheckRegisteredFunc, Func> accessTokenContainer_GetAccessTokenResultAsyncFunc, int invalidCredentialValue, Func> fun, string accessTokenOrAppId = null, bool retryIfFaild = true) where T : BaseJsonResult { //ApiHandlerWapperFactory.ApiHandlerWapperFactoryCollection["s"] = ()=> new Senparc.Weixin.MP.AdvancedAPIs.User.UserInfoJson(); //var platform = ApiHandlerWapperFactory.CurrentPlatform;//当前平台 string appId = null; string accessToken = null; if (accessTokenOrAppId == null) { appId = accessTokenContainer_GetFirstOrDefaultAppIdFunc();// AccessTokenContainer.GetFirstOrDefaultAppId(); if (appId == null) { throw new UnRegisterAppIdException(null, "尚无已经注册的AppId,请先使用AccessTokenContainer.Register完成注册(全局执行一次即可)!"); } } else if (ApiUtility.IsAppId(accessTokenOrAppId, platformType)) { //if (!AccessTokenContainer.CheckRegistered(accessTokenOrAppId)) if (!accessTokenContainer_CheckRegisteredFunc(accessTokenOrAppId)) { throw new UnRegisterAppIdException(accessTokenOrAppId, string.Format("此appId({0})尚未注册,请先使用AccessTokenContainer.Register完成注册(全局执行一次即可)!", accessTokenOrAppId)); } appId = accessTokenOrAppId; } else { accessToken = accessTokenOrAppId; //accessToken } T result = null; try { if (accessToken == null) { var accessTokenResult = await accessTokenContainer_GetAccessTokenResultAsyncFunc(appId, false);//AccessTokenContainer.GetAccessTokenResultAsync(appId, false); accessToken = accessTokenResult.access_token; } result = await fun(accessToken); } catch (ErrorJsonResultException ex) { if (retryIfFaild && appId != null //如果 appId 为 null,已经没有重试的意义(直接提供的 AccessToken 是错误的) //&& ex.JsonResult.errcode == ReturnCode.获取access_token时AppSecret错误或者access_token无效) && (int)ex.JsonResult.errcode == invalidCredentialValue) { //尝试重新验证(如果是低版本VS,此处不能使用await关键字,可以直接使用xx.Result输出。VS2013不支持:无法在 catch 字句体中等待) var accessTokenResult = await accessTokenContainer_GetAccessTokenResultAsyncFunc(appId, true);//AccessTokenContainer.GetAccessTokenResultAsync(appId, true); //强制获取并刷新最新的AccessToken accessToken = accessTokenResult.access_token; result = await TryCommonApiBaseAsync(platformType, accessTokenContainer_GetFirstOrDefaultAppIdFunc, accessTokenContainer_CheckRegisteredFunc, accessTokenContainer_GetAccessTokenResultAsyncFunc, invalidCredentialValue, fun, appId, false); //result = TryCommonApiAsync(fun, appId, false); } else { throw; } } return result; } #endregion #endif } }