真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

微信公眾平臺(tái)開發(fā)中AccessToken自動(dòng)管理機(jī)制的示例分析

這篇文章主要介紹了微信公眾平臺(tái)開發(fā)中AccessToken自動(dòng)管理機(jī)制的示例分析,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比天壇街道網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式天壇街道網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋天壇街道地區(qū)。費(fèi)用合理售后完善,10多年實(shí)體公司更值得信賴。

在實(shí)際的開發(fā)過程中,所有的高級(jí)接口都需要提供AccessToken,因此我們每次在調(diào)用高級(jí)接口之前,都需要執(zhí)行一次獲取AccessToken的方法,例如:

var accessToken = AccessTokenContainer.TryGetAccessToken(appId, appSecret);

或者當(dāng)你對(duì)appId和appSecret進(jìn)行過全局注冊(cè)之后,也可以這樣做:

var accessToken = AccessTokenContainer.GetAccessToken(_appId);

然后使用這個(gè)accessToken輸入到高級(jí)接口的方法中,例如我們可以這樣獲取菜單:

var result = CommonApi.GetMenu(accessToken);

通常情況下,這已經(jīng)是一個(gè)很簡(jiǎn)潔的API調(diào)用過程。但是我們不愿意就這樣停止,我們準(zhǔn)備把幾乎所有的API調(diào)用都縮短到一行。

這么做的同時(shí),除了讓代碼更加簡(jiǎn)便,我們還有兩個(gè)愿望:

讓API可以自動(dòng)處理已經(jīng)變更的AccessToken(在負(fù)載均衡等多個(gè)服務(wù)器同時(shí)操作同一個(gè)微信公眾號(hào)的情況下,可能出現(xiàn)AccessToken在外部被刷新,導(dǎo)致本機(jī)AccessToken失效的情況),并且重新獲取、返回最終正確的API結(jié)果。

不改變目前API調(diào)用的方式,完全向下兼容。

調(diào)用代碼

修改之后,我們可以直接這樣一行調(diào)用API,每次只需要提供一個(gè)appId:

var result = CommonApi.GetMenu(appId);

當(dāng)前在執(zhí)行之前,我們需要像以前一樣全局注冊(cè)一下appId和appSecret:

AccessTokenContainer.Register(_appId, _appSecret);//全局只需注冊(cè)一次,例如可以放在Global的Application_Start()方法中。

可以看到,原先的accessToken換成了appId(新版本仍然支持輸入accessToken),省去了獲取accessToken的過程。具體的過程見下文說明。

SDK源代碼實(shí)現(xiàn)過程

之前為了實(shí)現(xiàn)自動(dòng)處理(預(yù)料外的)過期的AccessToken,SDK已經(jīng)提供了Senparc.Weixin.MP/AccessTokenHandlerWapper.Do()方法。這次升級(jí)將AccessTokenHandlerWapper.cs重命名為ApiHandlerWapper.cs,廢除Do()方法,添加TryCommonApi()方法,代碼如下:

namespace Senparc.Weixin.MP
{
    /// 
    /// 針對(duì)AccessToken無效或過期的自動(dòng)處理類
    /// 
    public static class ApiHandlerWapper
    {
        /// 
        /// 使用AccessToken進(jìn)行操作時(shí),如果遇到AccessToken錯(cuò)誤的情況,重新獲取AccessToken一次,并重試。
        /// 使用此方法之前必須使用AccessTokenContainer.Register(_appId, _appSecret);或JsApiTicketContainer.Register(_appId, _appSecret);方法對(duì)賬號(hào)信息進(jìn)行過注冊(cè),否則會(huì)出錯(cuò)。
        /// 
        /// 
        /// 
        /// AccessToken或AppId。如果為null,則自動(dòng)取已經(jīng)注冊(cè)的第一個(gè)appId/appSecret來信息獲取AccessToken。
        /// 請(qǐng)保留默認(rèn)值true,不用輸入。
        /// 
        public static T TryCommonApi(Func fun, string accessTokenOrAppId = null, bool retryIfFaild = true) where T : WxJsonResult
        {
            string appId = null;
            string accessToken = null;
 
            if (accessTokenOrAppId == null)
            {
                appId = AccessTokenContainer.GetFirstOrDefaultAppId();
                if (appId == null)
                {
                    throw new WeixinException("尚無已經(jīng)注冊(cè)的AppId,請(qǐng)先使用AccessTokenContainer.Register完成注冊(cè)(全局執(zhí)行一次即可)!");
                }
            }
            else if (ApiUtility.IsAppId(accessTokenOrAppId))
            {
                if (!AccessTokenContainer.CheckRegistered(accessTokenOrAppId))
                {
                    throw new WeixinException("此appId尚未注冊(cè),請(qǐng)先使用AccessTokenContainer.Register完成注冊(cè)(全局執(zhí)行一次即可)!");
                }
 
                appId = accessTokenOrAppId;
            }
            else
            {
                //accessToken
                accessToken = accessTokenOrAppId;
            }
 
 
            T result = null;
 
            try
            {
                if (accessToken == null)
                {
                    var accessTokenResult = AccessTokenContainer.GetAccessTokenResult(appId, false);
                    accessToken = accessTokenResult.access_token;
                }
                result = fun(accessToken);
            }
            catch (ErrorJsonResultException ex)
            {
                if (!retryIfFaild
                    && appId != null
                    && ex.JsonResult.errcode == ReturnCode.獲取access_token時(shí)AppSecret錯(cuò)誤或者access_token無效)
                {
                    //嘗試重新驗(yàn)證
                    var accessTokenResult = AccessTokenContainer.GetAccessTokenResult(appId, true);
                    accessToken = accessTokenResult.access_token;
                    result = TryCommonApi(fun, appId, false);
                }
            }
            return result;
        }
    }
}

對(duì)應(yīng)API的源代碼原來是這樣的:

/// 
/// 獲取當(dāng)前菜單,如果菜單不存在,將返回null
/// 
/// 
/// 
public static GetMenuResult GetMenu(string accessToken)
{
    var url = string.Format("https://api.weixin.qq.com/cgi-bin/menu/get?access_token={0}", accessToken);
 
    var jsonString = HttpUtility.RequestUtility.HttpGet(url, Encoding.UTF8);
    //var finalResult = GetMenuFromJson(jsonString);
 
    GetMenuResult finalResult;
    JavaScriptSerializer js = new JavaScriptSerializer();
    try
    {
        var jsonResult = js.Deserialize(jsonString);
        if (jsonResult.menu == null || jsonResult.menu.button.Count == 0)
        {
            throw new WeixinException(jsonResult.errmsg);
        }
 
        finalResult = GetMenuFromJsonResult(jsonResult);
    }
    catch (WeixinException ex)
    {
        finalResult = null;
    }
 
    return finalResult;
}

現(xiàn)在使用TryCommonApi()方法之后:

/// 
/// 獲取當(dāng)前菜單,如果菜單不存在,將返回null
/// 
/// AccessToken或AppId。當(dāng)為AppId時(shí),如果AccessToken錯(cuò)誤將自動(dòng)獲取一次。當(dāng)為null時(shí),獲取當(dāng)前注冊(cè)的第一個(gè)AppId。
/// 
public static GetMenuResult GetMenu(string accessTokenOrAppId)
{
    return ApiHandlerWapper.TryCommonApi(accessToken =>
      {
          var url = string.Format("https://api.weixin.qq.com/cgi-bin/menu/get?access_token={0}", accessToken);
 
          var jsonString = HttpUtility.RequestUtility.HttpGet(url, Encoding.UTF8);
          //var finalResult = GetMenuFromJson(jsonString);
 
          GetMenuResult finalResult;
          JavaScriptSerializer js = new JavaScriptSerializer();
          try
          {
              var jsonResult = js.Deserialize(jsonString);
              if (jsonResult.menu == null || jsonResult.menu.button.Count == 0)
              {
                  throw new WeixinException(jsonResult.errmsg);
              }
 
              finalResult = GetMenuFromJsonResult(jsonResult);
          }
          catch (WeixinException ex)
          {
              finalResult = null;
          }
 
          return finalResult;
      }, accessTokenOrAppId);
}

我們可以觀察到有這樣幾處變化:

1. 原先的accessToken變量名稱改為了accessTokenOrAppId(新版本中所有相關(guān)接口都將如此變化)。

修改之后,這個(gè)參數(shù)可以輸入accessToken(向下兼容),也可以輸入appId(無需再獲取accessToken),SDK會(huì)根據(jù)字符串長(zhǎng)度自動(dòng)判斷屬于哪種類型的參數(shù)。提供的參數(shù)有3種可能:

a) appId。使用appId需要事先對(duì)appId和appSecret進(jìn)行全局注冊(cè)(上文已說過),當(dāng)調(diào)用API的過程中發(fā)現(xiàn)緩存的AccessToken過期時(shí),SDK會(huì)自動(dòng)刷新AccessToken,并重新嘗試一次API請(qǐng)求,確保返回正確的結(jié)果。如果appId沒有被注冊(cè)過,會(huì)拋出異常。

b) accessToken。這種情況下將使用原始的請(qǐng)求方式,如果accessToken無效,將直接拋出異常,不會(huì)重試。

c) null。當(dāng)accessTokenOrAppId參數(shù)為null時(shí),SDK會(huì)自動(dòng)獲取全局注冊(cè)的第一個(gè)appId。如果某個(gè)應(yīng)用只針對(duì)一個(gè)確定的微信號(hào)開發(fā),可以使用這種方法。當(dāng)全局沒有注冊(cè)任何appId時(shí),將拋出異常。

2. 原方法內(nèi)的訪問API的代碼沒有做任何修改,只是被嵌套到了return ApiHandlerWapper.TryCommonApi(accessToken =>{...},accessTokenOrAppId)的方法中,以委托的形式出現(xiàn),目的是為了在第一次可能的請(qǐng)求失敗之后,SDK可以自動(dòng)執(zhí)行一次一模一樣的代碼。

此功能已經(jīng)在Senparc.Weixin.MP v12.1中發(fā)布。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“微信公眾平臺(tái)開發(fā)中AccessToken自動(dòng)管理機(jī)制的示例分析”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!


本文題目:微信公眾平臺(tái)開發(fā)中AccessToken自動(dòng)管理機(jī)制的示例分析
標(biāo)題路徑:http://weahome.cn/article/jdieij.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部