背景描述:进入公众号首页时,需要获取用户的openid,用来判断该openid是否存在于用户表,如果已经存在就省略登录的步骤,直接进入公众号。今天遇到这样一个问题:获取不到openid,无法进入公众号。
原因:redirect之后仍然执行后续代码,导致**“未将对象引用到实例”的错误**。
例如下面这个例子,获取openid的方法是先获得code,再根据code取openid。正常来说,会跑两次HomeController控制器里的index方法。但是由于第一次获取code时重定向之后还会继续执行后续的代码,openid还没取到就直接tostring,导致了null的错误,所以第一次就跑不下去了。
HomeController.cs(修改前的代码):
public ActionResult Index()
{
var encry = new Encrypt();
var openID = "";
if (string.IsNullOrWhiteSpace(Session["openID"]?.ToString()))
{
GetUserInfo gui= new GetUserInfo(this);
gui.GetOpenid();
openID = gui.openid;
openID = Convert.ToBase64String(Encoding.UTF8.GetBytes(encry.Encrypto(openID.ToString()))); //这里会报“未将对象引用到实例”的错误
Session.Add("openID", openID);
}
return View();
}
GetUserInfo.cs:
public class GetUserInfo
{
private Controller page {get;set;}
public string openid { get; set; }
public GetUserInfo(Controller page)
{
this.page = page;
}
string strAppid="123456789";
string strSecret="123123123";
public void GetOpenid()
{
if (!string.IsNullOrEmpty(page.Request.QueryString["code"]))
{
string code = page.Request.QueryString["code"];
GetOpenidByCode(code);
}
else
{
string host = page.Request.Url.Host;
string path = page.Request.Path;
string redirect_uri = HttpUtility.UrlEncode("http://" + host + path);
string url = "https://open.weixin.qq.com/connect/oauth2/authorize?" + "appid="+strAppid+"&redirect_uri="+redirect_uri+"&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
page.Response.Redirect(url); //重定向页面,返回code
}
}
public void GetOpenidByCode(string code)
{
try
{
string url = "https://api.weixin.qq.com/sns/oauth2/access_token?" + "appid=" + strAppid + "&secret=" + strSecret + "&code=" + code + "&grant_type=authorization_code";
//请求url以获取数据
string result = HttpService.Get(url);
JsonData jd = JsonMapper.ToObject(result);
access_token = (string)jd["access_token"];
openid = (string)jd["openid"];
}
catch (Exception ex)
{
throw new WxPayException(ex.ToString());
}
}
}
HomeController.cs(修改后的代码):
public ActionResult Index()
{
var encry = new Encrypt();
var openID = "";
if (string.IsNullOrWhiteSpace(Session["openID"]?.ToString()))
{
GetUserInfo gui= new GetUserInfo(this);
gui.GetOpenid();
openID = gui.openid;
if (openID == null) //首次加载页面是获取code,还不能获取到openid。所以用EmptyResult来阻止后续代码的执行,立即重定向
{
return new EmptyResult();
}
openID = Convert.ToBase64String(Encoding.UTF8.GetBytes(encry.Encrypto(openID.ToString())));
Session.Add("openID", openID);
}
return View();
}
解决办法参考自这篇文章:https://www.cnblogs.com/OpenCoder/p/5421464.html