首先说下需求:
我有一个网站,网站上有很多作者分享自己的作品,如果其他用户浏览作品后想联系这位作者,就需要扫码关注我们的平台,我们会推送对方的联系方式。
第一步,生成带参数的二维码
步骤:
1.用微信appid和appsecret获取access_token
2.用access_token获取二维码的ticket,这其中要用json格式传入固定格式的值才能获取到ticket,传值的时候你可以在scene_id中带上自己的参数,方便用户扫码后回调的时候处理
3.用ticket直接得到二维码图片(注意:用这个方式,微信服务器返回的是图片的数据流。如果你需要处理二维码的图片,你不需要考虑如何操作这个数据流,只需要把整个访问微信的字符串带上ticket当成一个图片的地址放在src中就可以了,你可以操作图片本身)
下面是代码,省略了一些处理返回值的model类
///
/// 生成二维码
///
///
[HttpPost]
public IHttpActionResult CreateImg(dynamic data)
{
//用户ID
int uid = Convert.ToInt32(data.userid);
//get token
string url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=**********&secret=****************");
var wm = new System.Net.Http.HttpClient().GetAsync(url).Result.Content.ReadAsStringAsync().Result;
WechatModels info = JsonConvert.DeserializeObject(wm);
//get ticket
string turl = string.Format("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={0}", info.access_token);
var jsonInfo = "{\"action_name\": \"QR_LIMIT_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": " + uid + "}}}";
HttpContent httpContent = new StringContent(jsonInfo);
httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
var tickets = new System.Net.Http.HttpClient().PostAsync(turl, httpContent).Result.Content.ReadAsStringAsync().Result;
TicketInfo tinfo = JsonConvert.DeserializeObject(tickets);
//get imgUrl
string imgUrl = string.Format("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={0}", System.Web.HttpUtility.UrlEncode(tinfo.ticket));
//var res = new System.Net.Http.HttpClient().GetAsync(imgUrl).Result.Content.ReadAsStringAsync().Result;
return Json(imgUrl);
}
第二步,用户扫码后的处理
处理的前提是你已经在公众号中配置完成
如图,服务器地址中的方法,就是扫码后的回调地址,也是之前一开始你配置服务器时处理token的回调地址
下面插入回调处理的代码
///
/// 接收微信推送
///
public void Valid()
{
Stream requestStream = System.Web.HttpContext.Current.Request.InputStream;
string result = "";
string postString = string.Empty;
//处理扫码后的回调,参考微信公众平台开发文档中给出的回调数据
if (System.Web.HttpContext.Current.Request.HttpMethod.ToUpper() == "POST")
{
using (Stream stream = System.Web.HttpContext.Current.Request.InputStream)
{
Byte[] postBytes = new Byte[stream.Length];
stream.Read(postBytes, 0, (Int32)stream.Length);
postString = Encoding.UTF8.GetString(postBytes);
if (!string.IsNullOrEmpty(postString))
{
string SendToWx = string.Empty;
//这里写方法解析Xml
XmlDocument xml = new XmlDocument();//
xml.LoadXml(postString);
XmlElement xmlElement = xml.DocumentElement;
//这里进行判断MsgType
switch (xmlElement.SelectSingleNode("MsgType").InnerText)
{
case "voice":
break;
case "video":
break;
case "shortvideo":
break;
case "location":
break;
case "link":
break;
case "event":
//扫码后的MsgType是event,在这里解析微信服务器的推送数据,我们再按照要求的格式推送给用户
string FromUserName = xmlElement.SelectSingleNode("FromUserName").InnerText == null ? "" : xmlElement.SelectSingleNode("FromUserName").InnerText;
string ToUserName = xmlElement.SelectSingleNode("ToUserName").InnerText == null ? "" : xmlElement.SelectSingleNode("ToUserName").InnerText;
string CreateTime = xmlElement.SelectSingleNode("CreateTime").InnerText == null ? "" : xmlElement.SelectSingleNode("CreateTime").InnerText;
string eventKey = xmlElement.SelectSingleNode("EventKey").InnerText == null ? "" : xmlElement.SelectSingleNode("EventKey").InnerText;
//这里需要注意,扫码后的eventKey就是你之前的场景值,但是如果用户没有关注,用户先选择了关注,那这里的eventKey就会多一个“qrscene_”的前缀,这在文档中有说明,但容易忽略,所以这里做一下处理
if (eventKey.Contains("_")) { eventKey = eventKey.Split('_')[1]; }
//我在这里通过场景值来查询用户信息,再把用户需要的信息发送出去
var user = Helper.Comm.HttpPost2(ip + "/api/Index/QueryWorks", new Dictionary()
{
{ "uid", eventKey }
});
TalentPool contents = JsonConvert.DeserializeObject(user);
//把联系方式发送给对方
string tips = "感谢关注!" + contents.Name + "的微信号是:" + contents.WX + " ";
//拼接xml或json格式的数据,才能正确发送给用户
string jsoninfo = "" + CreateTime + " ";
//把数据转化为json格式
HttpContent httpContent = new StringContent(jsoninfo);
httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
switch (xmlElement.SelectSingleNode("Event").InnerText)
{
case "subscribe":
System.Web.HttpContext.Current.Response.Write(jsoninfo);//关注事件 通过C#自带的Response.Write方法,就能把需要的信息发给扫码的人
System.Web.HttpContext.Current.Response.End();
break;
case "unsubscribe":
System.Web.HttpContext.Current.Response.Write(jsoninfo);
System.Web.HttpContext.Current.Response.End();
break;
case "SCAN":
System.Web.HttpContext.Current.Response.Write(jsoninfo);//扫码事件
System.Web.HttpContext.Current.Response.End();
break;
case "LOCATION":
break;
case "CLICK":
break;
case "VIEW":
break;
default:
break;
}
break;
default:
result = "没有识别的类型消息:" + xmlElement.SelectSingleNode("MsgType").InnerText;
WriteLog(result);
break;
}
if (!string.IsNullOrEmpty(SendToWx))
{
System.Web.HttpContext.Current.Response.Write(SendToWx);
System.Web.HttpContext.Current.Response.End();
}
else
{
result = "回传数据为空";
WriteLog(result);
}
}
else
{
result = "微信推送的数据为:" + postString;
WriteLog(result);
}
}
}
else if (Request.HttpMethod.ToUpper() == "GET")
{
//这里是之前你配置微信服务的时候验证token令牌的方法处理,可以删掉但没必要
string token = ConfigurationManager.AppSettings["WXToken"];//从配置文件获取Token
if (string.IsNullOrEmpty(token))
{
result = string.Format("微信Token配置项没有配置!");
WriteLog(result);
}
string echoString = System.Web.HttpContext.Current.Request.QueryString["echoStr"];
string signature = System.Web.HttpContext.Current.Request.QueryString["signature"];
string timestamp = System.Web.HttpContext.Current.Request.QueryString["timestamp"];
string nonce = System.Web.HttpContext.Current.Request.QueryString["nonce"];
if (CheckSignature(token, signature, timestamp, nonce))
{
if (!string.IsNullOrEmpty(echoString))
{
System.Web.HttpContext.Current.Response.Write(echoString);
System.Web.HttpContext.Current.Response.End();
result = string.Format("微信Token配置成功,你已成为开发者!");
WriteLog(result);
}
}
}
}
//token验证
public bool CheckSignature(string token, string signature, string timestamp, string nonce)
{
string[] ArrTmp = { token, timestamp, nonce };
Array.Sort(ArrTmp);
string tmpStr = string.Join("", ArrTmp);
tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
tmpStr = tmpStr.ToLower();
if (tmpStr == signature)
{
return true;
}
else
{
return false;
}
}
//写入日志
private void WriteLog(string str)
{
try
{
using (System.IO.FileStream fs = new System.IO.FileStream(Server.MapPath("Upload/log.txt"), System.IO.FileMode.Append))
{
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(fs))
{
string strlog = "----" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":" + str + "-----";
sw.WriteLine(strlog);
sw.Close();
}
}
}
catch
{ }
}
至此你就完成了用户扫码后获得自定义消息的流程,代码中省略了一些前端的处理,以及一些实体类的代码,但不影响阅读
微信公众平台中,提供了日志查看的功能,微信开发调试起来并不那么方便,可以通过日志来查看
总体来讲,微信开发文档基本很简洁,没有什么案例,网上的资料很多也是无效的资料,对于新手来讲,微信开发确实是比较头痛,在此记录一下,希望这篇案例对大家有帮助。