123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- #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
- {
- /// <summary>
- /// 所有子模块ApiHandlerWapper方法调用的基础方法
- /// </summary>
- public class ApiHandlerWapperBase
- {
- #region 同步方法
- /// <summary>
- /// TryCommonApi 方法的基类
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="platformType">平台类型,PlatformType枚举</param>
- /// <param name="accessTokenContainer_GetFirstOrDefaultAppIdFunc">AccessTokenContainer中的GetFirstOrDefaultAppId()方法</param>
- /// <param name="accessTokenContainer_CheckRegisteredFunc">AccessTokenContainer中的bool CheckRegistered(appId,getNew)方法</param>
- /// <param name="accessTokenContainer_GetAccessTokenResultFunc">AccessTokenContainer中的AccessTokenResult GetAccessTokenResult(appId)方法</param>
- /// <param name="invalidCredentialValue">"ReturnCode.获取access_token时AppSecret错误或者access_token无效"枚举的值</param>
- /// <param name="fun"></param>
- /// <param name="accessTokenOrAppId"></param>
- /// <param name="retryIfFaild"></param>
- /// <returns></returns>
- public static T TryCommonApiBase<T>(
- PlatformType platformType,
- Func<string> accessTokenContainer_GetFirstOrDefaultAppIdFunc,
- Func<string, bool> accessTokenContainer_CheckRegisteredFunc,
- Func<string, bool, IAccessTokenResult> accessTokenContainer_GetAccessTokenResultFunc,
- int invalidCredentialValue,
- Func<string, T> 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 异步方法
- /// <summary>
- /// TryCommonApi 方法的基类
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="platformType">平台类型,PlatformType枚举</param>
- /// <param name="accessTokenContainer_GetFirstOrDefaultAppIdFunc">AccessTokenContainer中的GetFirstOrDefaultAppId()方法</param>
- /// <param name="accessTokenContainer_CheckRegisteredFunc">AccessTokenContainer中的bool CheckRegistered(appId,getNew)方法</param>
- /// <param name="accessTokenContainer_GetAccessTokenResultAsyncFunc">AccessTokenContainer中的AccessTokenResult GetAccessTokenResultAsync(appId)方法(异步方法)</param>
- /// <param name="invalidCredentialValue">"ReturnCode.获取access_token时AppSecret错误或者access_token无效"枚举的值</param>
- /// <param name="fun"></param>
- /// <param name="accessTokenOrAppId"></param>
- /// <param name="retryIfFaild"></param>
- /// <returns></returns>
- public static async Task<T> TryCommonApiBaseAsync<T>(
- PlatformType platformType,
- Func<string> accessTokenContainer_GetFirstOrDefaultAppIdFunc,
- Func<string, bool> accessTokenContainer_CheckRegisteredFunc,
- Func<string, bool, Task<IAccessTokenResult>> accessTokenContainer_GetAccessTokenResultAsyncFunc,
- int invalidCredentialValue,
- Func<string, Task<T>> 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
- }
- }
|