public IAsyncResult BeginGetUserInfo(string openID, WeChatLanguage language, AsyncCallback callback, object userState)
        {
            AsyncResult <IWeChatUserInfo> result = new AsyncResult <IWeChatUserInfo>(callback, userState);

            this.PerformAsyncGetAction <WeChatUserInfo>(result, (token) => string.Format(
                                                            "https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang={2}",
                                                            HttpUtility.UrlEncode(token),
                                                            HttpUtility.UrlEncode(openID),
                                                            HttpUtility.UrlEncode(EnumUtility.GetDescription(language))), (error, value) => {
                result.MarkCompleted(error, value);
            });
            return(result);
        }
        public IAsyncResult BeginGetOAuthUserInfo(string accessToken, string openID, WeChatLanguage language, AsyncCallback callback, object userState)
        {
            if (string.IsNullOrWhiteSpace(accessToken))
            {
                throw new ArgumentException("OAuth access token is null or empty.", "accessToken");
            }
            if (string.IsNullOrWhiteSpace(openID))
            {
                throw new ArgumentException("openID is null or empty.", "openID");
            }

            AsyncResult <IWeChatOAuthUserInfo> result = new AsyncResult <IWeChatOAuthUserInfo>(callback, userState);

            this.SendGetRequest <WeChatOAuthUserInfo>(string.Format(
                                                          "https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang={2}",
                                                          HttpUtility.UrlEncode(accessToken),
                                                          HttpUtility.UrlEncode(openID),
                                                          HttpUtility.UrlEncode(EnumUtility.GetDescription(language))), (error, value) => {
                result.MarkCompleted(error, value);
            });
            return(result);
        }