C#微信公衆號開發 -- (七)自定義菜單事件之VIEW及網頁(OAuth2.0)受權

通俗來說VIEW其實就是咱們在C#中經常使用的a標籤,能夠直接在自定義菜單URL的屬性裏面寫上須要跳轉的連接,也即爲單純的跳轉。html

但更多的狀況下,咱們是想經過VIEW來進入指定的頁面並進行操做。數據庫

舉一個簡單的例子,假如咱們的後臺須要記錄有哪些用戶在什麼時間訪問了哪一個網頁,那麼這就須要當用戶點擊VIEW的時候咱們程序記錄json

因此微信官方提供了一個很好的解決方案,那就是將VIEW與網頁受權獲取用戶信息相結合來實現api

咱們以建好的自定義菜單中的"搜索"VIEW爲例,來簡單的時候上面的操做。數組

首先將自定義菜單從新URL從新從新寫入網頁受權的連接,以及新建一個網頁受權的頁面OAuthRedirectUrl.aspx。微信

{
     "button":[
     {    
          "type":"click",
          "name":"今日歌曲",
          "key":"V1001_TODAY_MUSIC"
      },
      {
           "type":"click",
           "name":"歌手簡介",
           "key":"V1001_TODAY_SINGER"
      },
      {
           "name":"菜單",
           "sub_button":[
           {    
               "type":"view",
               "name":"搜索",
               "url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的微信公衆號appid&redirect_uri=http://xxx.com/WeiXin/OAuthRedirectUrl.aspx?reurl=so&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"
            },
            {
               "type":"view",
               "name":"視頻",
               "url":"http://v.qq.com/"
            },
            {
               "type":"click",
               "name":"贊一下咱們",
               "key":"V1001_GOOD"
            }]
       }]
 }

來看一下微信官方對這一串URL的參數解釋:app

 

參數 是否必須 說明
appid 公衆號的惟一標識
redirect_uri 受權後重定向的回調連接地址,請使用urlencode對連接進行處理
response_type 返回類型,請填寫code
scope 應用受權做用域,snsapi_base (不彈出受權頁面,直接跳轉,只能獲取用戶openid),snsapi_userinfo (彈出受權頁面,可經過openid拿到暱稱、性別、所在地。而且,即便在未關注的狀況下,只要用戶受權,也能獲取其信息
state 重定向後會帶上state參數,開發者能夠填寫a-zA-Z0-9的參數值,最多128字節
#wechat_redirect 不管直接打開仍是作頁面302重定向時候,必須帶此參數

其中參數redirect_uri也就是上面提到新建的頁面OAuthRedirectUrl.aspx,也就是說在跳轉到想要的頁面以前,先要到OAuthRedirectUrl.aspx去進行受權並獲取用戶基本信息,從而供本身使用。函數

OAuthRedirectUrl.aspx要作的操做其實也是很簡單,完成微信指定的受權。post

private string _appid = "你的微信公衆號appid";
        private string _appsecret = "你的微信公衆號appsecret";
        private string reurl = "";
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                //獲取傳過來的值
                if (Request.QueryString["reurl"] != null && Request.QueryString["reurl"].ToString() != "")
                {
                    reurl = Request.QueryString["reurl"].ToString();
                }
                string code = "";
                if (Request.QueryString["code"] != null && Request.QueryString["code"] != "")
                {
                    code = Request.QueryString["code"].ToString();
                    OAuth_Token Model = Get_token(code);
                    OAuthUser OAuthUser_Model = Get_UserInfo(Model.access_token, Model.openid);
                    //"http://xx.com/" + reurl + ".aspx?openid=" + OAuthUser_Model.openid;
                    string strurl = "";
                    switch (reurl)
                    {
                        case "so":
                            strurl = "http://www.cnblogs.com/HappyAnt/";
                            break;
                    }

                    Response.Redirect(strurl);
                    //Response.Write("reurl:" + reurl + ",code:" + code + ",openid:" + OAuthUser_Model.openid);
                }
            }
        }

        //得到Token
        protected OAuth_Token Get_token(string Code)
        {
            string Str = GetJson("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + _appid + "&secret=" + _appsecret + "&code=" + Code + "&grant_type=authorization_code");
            OAuth_Token Oauth_Token_Model = JsonHelper.ParseFromJson<OAuth_Token>(Str);
            return Oauth_Token_Model;
        }
        //刷新Token
        protected OAuth_Token refresh_token(string REFRESH_TOKEN)
        {
            string Str = GetJson("https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + _appid + "&grant_type=refresh_token&refresh_token=" + REFRESH_TOKEN);
            OAuth_Token Oauth_Token_Model = JsonHelper.ParseFromJson<OAuth_Token>(Str);
            return Oauth_Token_Model;
        }
        //得到用戶信息
        protected OAuthUser Get_UserInfo(string REFRESH_TOKEN, string OPENID)
        {
            // Response.Write("得到用戶信息REFRESH_TOKEN:" + REFRESH_TOKEN + "||OPENID:" + OPENID);
            string Str = GetJson("https://api.weixin.qq.com/sns/userinfo?access_token=" + REFRESH_TOKEN + "&openid=" + OPENID);
            OAuthUser OAuthUser_Model = JsonHelper.ParseFromJson<OAuthUser>(Str);
            return OAuthUser_Model;
        }
        protected string GetJson(string url)
        {
            WebClient wc = new WebClient();
            wc.Credentials = CredentialCache.DefaultCredentials;
            wc.Encoding = Encoding.UTF8;
            string returnText = wc.DownloadString(url);

            if (returnText.Contains("errcode"))
            {
                //可能發生錯誤
            }
            //Response.Write(returnText);
            return returnText;
        }
    }

    

    public class OAuth_Token
    {
        public OAuth_Token()
        {
            //
            //TODO: 在此處添加構造函數邏輯
            //
        }
        //access_token    網頁受權接口調用憑證,注意:此access_token與基礎支持的access_token不一樣
        //expires_in    access_token接口調用憑證超時時間,單位(秒)
        //refresh_token    用戶刷新access_token
        //openid    用戶惟一標識,請注意,在未關注公衆號時,用戶訪問公衆號的網頁,也會產生一個用戶和公衆號惟一的OpenID
        //scope    用戶受權的做用域,使用逗號(,)分隔
        public string access_token { get; set; }
        public string expires_in { get; set; }
        public string refresh_token { get; set; }
        public string openid { get; set; }
        public string scope { get; set; }
    }

    public class OAuthUser
    {
        public OAuthUser()
        { }
        #region 數據庫字段
        private string _openID;
        private string _searchText;
        private string _nickname;
        private string _sex;
        private string _province;
        private string _city;
        private string _country;
        private string _headimgUrl;
        private string _privilege;
        #endregion

        #region 字段屬性
        /// <summary>
        /// 用戶的惟一標識
        /// </summary>
        public string openid
        {
            set { _openID = value; }
            get { return _openID; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string SearchText
        {
            set { _searchText = value; }
            get { return _searchText; }
        }
        /// <summary>
        /// 用戶暱稱 
        /// </summary>
        public string nickname
        {
            set { _nickname = value; }
            get { return _nickname; }
        }
        /// <summary>
        /// 用戶的性別,值爲1時是男性,值爲2時是女性,值爲0時是未知 
        /// </summary>
        public string sex
        {
            set { _sex = value; }
            get { return _sex; }
        }
        /// <summary>
        /// 用戶我的資料填寫的省份
        /// </summary>
        public string province
        {
            set { _province = value; }
            get { return _province; }
        }
        /// <summary>
        /// 普通用戶我的資料填寫的城市 
        /// </summary>
        public string city
        {
            set { _city = value; }
            get { return _city; }
        }
        /// <summary>
        /// 國家,如中國爲CN 
        /// </summary>
        public string country
        {
            set { _country = value; }
            get { return _country; }
        }
        /// <summary>
        /// 用戶頭像,最後一個數值表明正方形頭像大小(有0、4六、6四、9六、132數值可選,0表明640*640正方形頭像),用戶沒有頭像時該項爲空
        /// </summary>
        public string headimgurl
        {
            set { _headimgUrl = value; }
            get { return _headimgUrl; }
        }
        /// <summary>
        /// 用戶特權信息,json 數組,如微信沃卡用戶爲(chinaunicom)其實這個格式稱不上JSON,只是個單純數組
        /// </summary>
        public string privilege
        {
            set { _privilege = value; }
            get { return _privilege; }
        }
        #endregion
    }

要點:url

1:頁面上面必需要有接受code的代碼,由於code要換取一個特殊的網頁受權access_token

2:C#微信公衆號開發 -- (四)獲取API調用所需的全局惟一票據access_token 與此次的網頁受權access_token不是一個值,也不是一個概念。

3:在頁面中須要生成OAuth_Token,OAuthUser兩個類,與微信提供的字段要徹底吻合(更好的方式是讓這兩個類進行封裝)

4:strurl中還能夠寫上帶參數的連接,想獲取的客戶信息只須要在OAuthUser_Model讀取就行了

5:通常的程序開發還暫時用不到「刷新Token」的方法,反正我如今是一直沒用到,這裏做爲了解就行了

6:若是你這些都配置好後,頁面卻顯示 」redirect_uri 參數錯誤」 ,那麼請注意讀微信的開發說明 

「在微信公衆號請求用戶網頁受權以前,開發者須要先到公衆平臺官網中的開發者中心頁配置受權回調域名」

以及檢查你的URL連接裏面參數有沒有錯誤,參數順序有沒有錯誤。

作完這些工做之後,就能夠真正意義上的實現跳轉了,也即實現了VIEW它自己應有的價值。
相關文章
相關標籤/搜索