public ActionResult OnLogin(string code)
        {
            try
            {
                var jsonResult = SnsApi.JsCode2Json(WxOpenAppId, WxOpenAppSecret, code);
                if (jsonResult.errcode == ReturnCode.请求成功)
                {
                    //Session["WxOpenUser"] = jsonResult;//使用Session保存登陆信息(不推荐)
                    //使用SessionContainer管理登录信息(推荐)
                    //var unionId = "";
                    var sessionBag = SessionContainer.UpdateSession(null, jsonResult.openid, jsonResult.session_key, jsonResult.unionid);

                    var userInfo = _userWeChatInfoServices.Exists(p => p.openid == jsonResult.openid);
                    if (userInfo == false)
                    {
                        var user = new CoreCmsUserWeChatInfo();
                        user.openid     = jsonResult.openid;
                        user.type       = (int)GlobalEnumVars.UserAccountTypes.微信小程序;
                        user.sessionKey = sessionBag.SessionKey;
                        user.gender     = 1;
                        user.createTime = DateTime.Now;
                        var id = _userWeChatInfoServices.Insert(user);
                        if (id > 0)
                        {
                            _userWeChatInfoServices.Update(p => new CoreCmsUserWeChatInfo()
                            {
                                userId = id
                            },
                                                           p => p.id == id);
                        }
                    }

                    //注意:生产环境下SessionKey属于敏感信息,不能进行传输!
                    //return Json(new { success = true, msg = "OK", sessionId = sessionBag.Key, sessionKey = sessionBag.SessionKey, data = jsonResult, sessionBag = sessionBag });
                    return(Json(new { success = true, msg = "OK", sessionId = sessionBag.Key }));
                }
                else
                {
                    return(Json(new { success = false, msg = jsonResult.errmsg }));
                }
            }
            catch (Exception ex)
            {
                return(Json(new { success = false, msg = ex.Message }));
            }
        }
        public IActionResult UserInfoCallback(string code, string state, string returnUrl)
        {
            if (string.IsNullOrEmpty(code))
            {
                return(Content("您拒绝了授权!"));
            }
            if (!state.StartsWith("FromSenparc") || !state.Contains("|") || state.Length != 30)
            {
                //这里的state其实是会暴露给客户端的,验证能力很弱,这里只是演示一下,
                //建议用完之后就清空,将其一次性使用
                //实际上可以存任何想传递的数据,比如用户ID,并且需要结合例如下面的Session["OAuthAccessToken"]进行验证
                return(Content("验证失败!请从正规途径进入!"));
            }
            OAuthAccessTokenResult result = null;

            //通过,用code换取access_token
            try
            {
                result = OAuthApi.GetAccessToken(appId, appSecret, code);
            }
            catch (Exception ex)
            {
                return(Content(ex.Message));
            }
            if (result.errcode != Senparc.Weixin.ReturnCode.请求成功)
            {
                return(Content("错误:" + result.errmsg));
            }
            //下面2个数据也可以自己封装成一个类,储存在数据库中(建议结合缓存)
            //如果可以确保安全,可以将access_token存入用户的cookie中,每一个人的access_token是不一样的
            HttpContext.Session.SetString("OAuthAccessTokenStartTime", SystemTime.Now.ToString());
            HttpContext.Session.SetString("OAuthAccessToken", result.ToJson());


            //因为第一步选择的是OAuthScope.snsapi_userinfo,这里可以进一步获取用户详细信息
            try
            {
                OAuthUserInfo userInfo       = OAuthApi.GetUserInfo(result.access_token, result.openid);
                var           weChatUserInfo = _userWeChatInfoServices.QueryByClause(p => p.openid == userInfo.openid);
                if (weChatUserInfo == null)
                {
                    weChatUserInfo            = new CoreCmsUserWeChatInfo();
                    weChatUserInfo.type       = (int)GlobalEnumVars.UserAccountTypes.微信公众号;
                    weChatUserInfo.openid     = userInfo.openid;
                    weChatUserInfo.sessionKey = result.access_token;
                    weChatUserInfo.unionId    = userInfo.unionid;
                    weChatUserInfo.avatar     = userInfo.headimgurl;
                    weChatUserInfo.nickName   = userInfo.nickname;
                    weChatUserInfo.gender     = userInfo.sex;
                    weChatUserInfo.language   = "";
                    weChatUserInfo.city       = userInfo.city;
                    weChatUserInfo.province   = userInfo.province;
                    weChatUserInfo.country    = userInfo.country;
                    weChatUserInfo.mobile     = "";
                    weChatUserInfo.createTime = DateTime.Now;
                    var id = _userWeChatInfoServices.Insert(weChatUserInfo);
                    if (id > 0)
                    {
                        weChatUserInfo.id = id;
                        _userWeChatInfoServices.Update(p => new CoreCmsUserWeChatInfo()
                        {
                            userId = id
                        }, p => p.id == id);
                    }
                }
                else
                {
                    if (weChatUserInfo.country != userInfo.country || weChatUserInfo.province != userInfo.province || weChatUserInfo.nickName != userInfo.nickname || weChatUserInfo.avatar != userInfo.headimgurl || weChatUserInfo.unionId != userInfo.unionid || weChatUserInfo.gender != userInfo.sex || weChatUserInfo.city != userInfo.city)
                    {
                        weChatUserInfo.city     = userInfo.city;
                        weChatUserInfo.country  = userInfo.country;
                        weChatUserInfo.province = userInfo.province;
                        weChatUserInfo.nickName = userInfo.nickname;
                        weChatUserInfo.gender   = userInfo.sex;
                        weChatUserInfo.avatar   = userInfo.headimgurl;
                        weChatUserInfo.unionId  = userInfo.unionid;
                        //weChatUserInfo.remark = bkurl;
                        _userWeChatInfoServices.Update(weChatUserInfo);
                    }
                }
                //缓存信息
                Response.Cookies.Append(GlobalConstVars.CookieOpenId, result.openid);
                HttpContext.Session.SetString(GlobalConstVars.SessionOpenId, result.openid);//进行登录
                if (!string.IsNullOrEmpty(returnUrl))
                {
                    return(Redirect(returnUrl));
                }
                return(View(userInfo));
            }
            catch (ErrorJsonResultException ex)
            {
                return(Content(ex.Message));
            }
        }
        public async Task <IActionResult> DecodeEncryptedData(string type, string sessionId, string encryptedData, string iv)
        {
            DecodeEntityBase      decodedEntity = null;
            CoreCmsUserWeChatInfo userInfo      = null;

            try
            {
                switch (type.ToUpper())
                {
                case "USERINFO":    //wx.getUserInfo()
                    decodedEntity = EncryptHelper.DecodeUserInfoBySessionId(sessionId, encryptedData, iv);
                    break;

                default:
                    break;
                }
            }
            catch (Exception ex)
            {
                WeixinTrace.SendCustomLog("EncryptHelper.DecodeUserInfoBySessionId 方法出错",
                                          $@"sessionId: {sessionId}encryptedData: {encryptedData}iv: {iv}sessionKey: { (await SessionContainer.CheckRegisteredAsync(sessionId)
                ? (await SessionContainer.GetSessionAsync(sessionId)).SessionKey
                : "未保存sessionId")}异常信息:{ex.ToString()}");
            }

            //检验水印
            var checkWatermark = false;

            if (decodedEntity != null)
            {
                checkWatermark = decodedEntity.CheckWatermark(WxOpenAppId);

                //保存用户信息(可选)
                if (checkWatermark && decodedEntity is DecodedUserInfo decodedUserInfo)
                {
                    var sessionBag = await SessionContainer.GetSessionAsync(sessionId);

                    if (sessionBag != null)
                    {
                        await SessionContainer.AddDecodedUserInfoAsync(sessionBag, decodedUserInfo);
                    }
                    //更新数据库讯息
                    userInfo = _userWeChatInfoServices.QueryByClause(p => p.openid == decodedUserInfo.openId);
                    if (userInfo == null)
                    {
                        userInfo            = new CoreCmsUserWeChatInfo();
                        userInfo.type       = (int)GlobalEnumVars.UserAccountTypes.微信小程序;
                        userInfo.openid     = decodedUserInfo.openId;
                        userInfo.sessionKey = sessionBag.SessionKey;
                        userInfo.unionId    = decodedUserInfo.unionId;
                        userInfo.avatar     = decodedUserInfo.avatarUrl;
                        userInfo.nickName   = decodedUserInfo.nickName;
                        userInfo.gender     = decodedUserInfo.gender;
                        userInfo.language   = "";
                        userInfo.city       = decodedUserInfo.city;
                        userInfo.province   = decodedUserInfo.province;
                        userInfo.country    = decodedUserInfo.country;
                        userInfo.mobile     = "";
                        userInfo.createTime = DateTime.Now;
                        var id = _userWeChatInfoServices.Insert(userInfo);
                        if (id > 0)
                        {
                            userInfo.id = id;
                            _userWeChatInfoServices.Update(p => new CoreCmsUserWeChatInfo()
                            {
                                userId = id
                            }, p => p.id == id);
                        }
                    }
                    else
                    {
                        userInfo.gender   = decodedUserInfo.gender;
                        userInfo.city     = decodedUserInfo.city;
                        userInfo.avatar   = decodedUserInfo.avatarUrl;
                        userInfo.country  = decodedUserInfo.country;
                        userInfo.nickName = decodedUserInfo.nickName;
                        userInfo.province = decodedUserInfo.province;
                        userInfo.unionId  = decodedUserInfo.unionId;
                        userInfo.gender   = decodedUserInfo.gender;
                        _userWeChatInfoServices.Update(userInfo);
                    }
                }
            }

            //注意:此处仅为演示,敏感信息请勿传递到客户端!
            return(Json(new
            {
                success = checkWatermark,
                userInfo = userInfo,
                msg = string.Format("水印验证:{0}",
                                    checkWatermark ? "通过" : "不通过")
            }));
        }