c#实现微信公众号开发--服务号通过oauth2获取用户信息

    2018年春节策划了一个“带现金红包的贺年卡”微信号推广活动,先说下效果:2个小时实现新增关注用户4万多户,活动页面PV达到16.8万,后因红包预算费用原因结束活动。

    实现原理:每个人都可以在服务号内发送一张自己的图片,生成定制贺卡,分享后(朋友圈、点对点发给好友、发送到微信群),好友可以打开页面,查看自己送出的祝福,同时还能领现金红包立即到账,并且:自己还能收到回礼红包,钱都由活动方来出,当然啦,领红包的前提是要关注指定微信公众号。

    每个人打开活动页面后,利用oauth2获取自己的openid,分享或转发时带上自己的openid,别人打开自己分享的贺卡页面时,获取分享人的openid,用来给其发送回礼红包,同时页面又会获取新打开人员自己的openid,用于领红包。就这样,可以实现无限级裂变传播。

    现将通过h5网页获取用户openid的方法步骤简要小结如下:

    1、准备认证过的微信服务号、web服务器、通过备案的域名;

    2、在公众号设置=》功能设置中设置“网页授权获取用户信息”中,设置自己服务器的域名,也就是公众号JS安全域名;

    3、以下为获取openid的核心代码;

第一个页面,用来获取code

testdir.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="testdir.aspx.cs" Inherits="testdir" %>


testdir.aspx.cs

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Linq;
using System.IO;
using System.Net;
using System.Text;
using System.Xml.Linq;
using Newtonsoft.Json;  
using Newtonsoft.Json.Converters; 
using Newtonsoft.Json.Linq; 


    public partial class testdir : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string openid = Request.QueryString["openid"];
            string periods = Request.QueryString["periods"];
    Response.Redirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的appid&redirect_uri=http://你的域名/testdirsec.aspx?openid="+openid+"|"+ periods +"&response_type=code&scope=snsapi_base&state=123#wechat_redirect");
        }
    }
   

第二个页面,用code来获取openid

testdirsec.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="testdirsec.aspx.cs" Inherits="testdirsec" %>


testdirsec.aspx.cs

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Linq;
using System.IO;
using System.Net;
using System.Text;
using System.Xml.Linq;
using Newtonsoft.Json;  
using Newtonsoft.Json.Converters; 
using Newtonsoft.Json.Linq; 
using GetOpenId;

    public partial class testdirsec : System.Web.UI.Page
    {
        
        protected void Page_Load(object sender, EventArgs e)
        {
    string all = Request.QueryString["openid"];  //因为oauth2只能传递一个自定义参数,顾自行分割
            string[] array=all.Split(new Char[] { '|' });
            string fromopenid=array[0];
            string periods=array[1];
            string code = Request.QueryString["code"]; 
            CGetOpenId goi=new CGetOpenId();
            

string openid  = goi.GetOpenId(code);
Response.Redirect("test.aspx?openid=" + openid + "&periods=" + periods +"&fromopenid=" + fromopenid);

        }
    }
   


第三个页面,活动页面,这里只把核心代码展现出来,常规布局没有罗列

test.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="test.aspx.cs" Inherits="test" %>







    我要抢红包
   
   

   
    
   
   
   



   




   




   





   









   



test.aspx.cs

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.IO;
using System.Text;
using System.Net;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using Newtonsoft.Json;  
using Newtonsoft.Json.Converters; 
using Newtonsoft.Json.Linq; 


public partial class test : System.Web.UI.Page
{
string fromopenid,openid,periods;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
fromopenid = Request.QueryString["fromopenid"];
openid = Request.QueryString["openid"];
periods = Request.QueryString["periods"];
lblfromopenid.Text = "fromopenid:" + fromopenid;
lblopenid.Text = "openid:" + openid;
lblperiods.Text = periods;
string strResult="";
string strurl="https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid + "&lang=zh_CN";    //获取用户信息的 AccessToken 
try
{
HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strurl);
//myReq.Timeout = timeout;
HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
Stream myStream = HttpWResp.GetResponseStream();
StreamReader sr = new StreamReader(myStream, Encoding.UTF8);
StringBuilder strBuilder = new StringBuilder();
while (-1 != sr.Peek())
{
strBuilder.Append(sr.ReadLine());
}
strResult = strBuilder.ToString();
}
catch
{
    strResult = "err";
}
JObject obj = (JObject)JsonConvert.DeserializeObject(HttpUtility.UrlDecode(strResult));

}
}

}

至此,获取openid已经实现,下面两个文件是用到的类和服务器端处理文件

GetOpenId.cs  //内含CGetOpenId类,放在App_Code目录下的,当然如果编译项目的话dll文件就在bin目录下了

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using Newtonsoft.Json;  
using Newtonsoft.Json.Converters; 
using Newtonsoft.Json.Linq; 


namespace GetOpenId
{
    public  class CGetOpenId : System.Web.UI.Page
    {
   public string GetOpenId(string code)
   {
string strResult="";
string openid="";
string strurl="https://api.weixin.qq.com/sns/oauth2/access_token?appid=你的公众号appid&secret=你的公众号secret&code="+ code +"&grant_type=authorization_code";


try
{
HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strurl);
//myReq.Timeout = timeout;
HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
Stream myStream = HttpWResp.GetResponseStream();
StreamReader sr = new StreamReader(myStream, Encoding.UTF8);
StringBuilder strBuilder = new StringBuilder();
while (-1 != sr.Peek())
{
strBuilder.Append(sr.ReadLine());
}
strResult = strBuilder.ToString();
}
catch
{
    strResult = "err";
}
JObject obj = (JObject)JsonConvert.DeserializeObject(HttpUtility.UrlDecode(strResult));
openid = obj["openid"].ToString().Replace("\"", "");
return openid;
   }
    }
}


getset.ashx  //在test.aspx中使用,放在服务器settest目录中

<% @ webhandler language="C#" class="getset" %>
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.IO;
using System.Net;
using System.Text;
using System.Drawing;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using Newtonsoft.Json;  
using Newtonsoft.Json.Converters; 
using Newtonsoft.Json.Linq;   
using System.Security.Cryptography;
using System.Web.Script.Serialization;
using GetToken;
using GetJSAPI;

public class getset : IHttpHandler
{


public void ProcessRequest(HttpContext ctx)
{
StreamReader sr=new StreamReader(ctx.Request.InputStream);
string stream = sr.ReadToEnd();
JObject jsonObj=JObject.Parse(stream);
string url=jsonObj["url"].ToString().Replace("\"","");
GetAT gt=new GetAT();
string accesstoken=gt.GetToken();
Getjsapi gj=new Getjsapi();
string jsapi=gj.GetAPI();
string timestamp=GetTimeStamp();
string nonceStr="Wm3WZYTfasdPz0wzccnW";
HttpContext.Current.Response.ContentType = "text/plain";
string content="jsapi_ticket="+jsapi+"&noncestr="+nonceStr+"×tamp="+timestamp+"&url="+url;
string sign=SHA1(content, Encoding.UTF8);
Dictionary dicList = new Dictionary();
dicList.Add("timestamp", timestamp);
dicList.Add("nonceStr", nonceStr);
dicList.Add("signature", sign);

string json =(new JavaScriptSerializer()).Serialize(dicList);


ctx.Response.Write(json);

}
//使用系统自带SHA加密
public  string SHA1(string content, Encoding encode)  
{  
try  
{  
SHA1 sha1 = new SHA1CryptoServiceProvider();  
byte[] bytes_in = encode.GetBytes(content);  
byte[] bytes_out = sha1.ComputeHash(bytes_in);  
//sha1.Dispose();  
string result = BitConverter.ToString(bytes_out);  
result = result.Replace("-", "");  
return result;  
}  
catch (Exception ex)  
{  
throw new Exception("SHA1" + ex.Message);  
}  
}  
//获取时间戳
public  string GetTimeStamp()  
{  
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);  
return Convert.ToInt64(ts.TotalSeconds).ToString();  
}  
public bool IsReusable
{
    get { return true; } 
}



GetToken.cs  //在getset.ashx中使用,放在App_Code目录中

//用于获取基础access_token,这个与网页access_token不同,每天使用次数上限为2000,单次有效期7200秒,所以使用数据库保存

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using Newtonsoft.Json;  
using Newtonsoft.Json.Converters; 
using Newtonsoft.Json.Linq; 
using DbOperate;


namespace GetToken
{
    public  class GetAT : System.Web.UI.Page
    {
public string GetToken()
{
SqlConnection Conn = new SqlConnection(SqlServerDB.ConnStr);
Conn.Open();
SqlCommand Comm = new SqlCommand();
Comm.Connection = Conn;
SqlDataReader dr;


string accesstoken="";
Comm.CommandText = "select appid,secret,accesstoken,DATEDIFF(second, get_date, getdate()) hour_num from weixin_accesstoken ";
dr=Comm.ExecuteReader();
if(dr.Read())
{
  if(Convert.ToInt32(dr["hour_num"].ToString())<=7000)
  {    
  accesstoken=dr["accesstoken"].ToString();
  dr.Close();
  }
  else
  {
  string strResult;
  string strurl="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ dr["appid"].ToString() +"&secret="+ dr["secret"].ToString()  +"";
  try
  {
  HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strurl);
  //myReq.Timeout = timeout;
  HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
  Stream myStream = HttpWResp.GetResponseStream();
  StreamReader sr = new StreamReader(myStream, Encoding.UTF8);
  StringBuilder strBuilder = new StringBuilder();
  while (-1 != sr.Peek())
  {
  strBuilder.Append(sr.ReadLine());
  }
  strResult = strBuilder.ToString();
  }
  catch
  {
  strResult = "err";
  }
  //accesstoken=strResult;
  //return strResult;
  JObject obj = (JObject)JsonConvert.DeserializeObject(HttpUtility.UrlDecode(strResult));
  accesstoken = obj["access_token"].ToString().Replace("\"", "");
  dr.Close();
  Comm.CommandText = "update weixin_accesstoken set accesstoken='"+ accesstoken +"',get_date=getdate()  ";
  Comm.ExecuteScalar();
   }
  
}


if (Conn.State == ConnectionState.Open)
{
   Conn.Close();
   Conn.Dispose();
}


return accesstoken;
}
    }

}


GetJSAPI.cs.cs  //在getset.ashx中使用,放在App_Code目录中

//用于获取time_ticket,也是单次有效时限7200秒,用数据库保存

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using Newtonsoft.Json;  
using Newtonsoft.Json.Converters; 
using Newtonsoft.Json.Linq; 
using GetToken;
using DbOperate;


namespace GetJSAPI
{
    public  class Getjsapi : System.Web.UI.Page
    {
public string GetAPI()
{
SqlConnection Conn = new SqlConnection(SqlServerDB.ConnStr);
Conn.Open();
SqlCommand Comm = new SqlCommand();
Comm.Connection = Conn;
SqlDataReader dr;

string ticket="";
Comm.CommandText = "select ticket,DATEDIFF(second, get_date, getdate()) time from weixin_jsapi ";
dr=Comm.ExecuteReader();
if(dr.Read())
{
if(Convert.ToInt32(dr["time"].ToString())<=7000)
{
ticket=dr["ticket"].ToString();
dr.Close();
}
else
{
GetAT gt=new GetAT();
string accesstoken=gt.GetToken();
string strResult;
string strurl="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+accesstoken+"&type=jsapi";
try
{
HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strurl);
//myReq.Timeout = timeout;
HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
Stream myStream = HttpWResp.GetResponseStream();
StreamReader sr = new StreamReader(myStream, Encoding.UTF8);
StringBuilder strBuilder = new StringBuilder();
while (-1 != sr.Peek())
{
strBuilder.Append(sr.ReadLine());
}
strResult = strBuilder.ToString();
}
catch
{
strResult = "err";
}
//accesstoken=strResult;
//return strResult;
JObject obj = (JObject)JsonConvert.DeserializeObject(HttpUtility.UrlDecode(strResult));
ticket = obj["ticket"].ToString().Replace("\"", "");
dr.Close();
Comm.CommandText = "update weixin_jsapi set ticket='"+ ticket +"',get_date=getdate()  ";
Comm.ExecuteScalar();
}
  
}

if (Conn.State == ConnectionState.Open)
{
Conn.Close();
Conn.Dispose();
}

return ticket;
}
}
}


你可能感兴趣的:(C#与ASP.NET)