首页 > 代码库 > .Net程序员关于微信公众平台测试账户配置 项目总结

.Net程序员关于微信公众平台测试账户配置 项目总结

今天项目第一次验收,夜晚吃过晚饭后,想把项目中用到的关于微信配置总结一下,虽然网上关于这方面的资料很多很多,还有官方API,但是总感觉缺点什么,就像期初做这个项目时,各方面找了很久的资料,说说配置吧!

1.你必须有一个微信可以访问的网站,然后有一个公众账户。

2.成为开发者。

上面这个URL填写你的网站的链接,微信服务器会放这个URL推送一些验证信息,具体验证信息,你可以查看官方API,写的很详细,因为我用的是MVC,所以我写了一个类,让控制器继承这个类,源码贴下,大家一看就明白。还有这个URL有很大用处,以后微信会往这个URL推送很多消息,比如用户的地理位置等,这里地理位置是微信推送给我们的,大家不要像我一样,理解错了,到时候会走很多弯路。

  1 using System;  2 using System.Collections.Generic;  3 using System.IO;  4 using System.Linq;  5 using System.Text;  6 using System.Web;  7 using System.Web.Mvc;  8 using System.Web.Security;  9 using System.Xml; 10  11 namespace SCKY.WebApp.Controllers 12 { 13     public class BaseController:Controller 14     { 15         //public Model.UCML_User LoginUser { get; set; } 16         const string Token = "123qweasd"; 17         protected override void OnActionExecuting(ActionExecutingContext filterContext) 18         { 19             string postStr = ""; 20             Valid(); 21             if (Request.HttpMethod.ToLower() == "post")//当普通微信用户向公众账号发消息时,微信服务器将POST该消息到填写的URL上 22             { 23                 postStr = PostInput(); 24                 if (string.IsNullOrEmpty(postStr) == false) 25                 { 26                     //WriteLog(postStr,Server);//计入日记 27                     //ResponseMsg(postStr); 28                 } 29                 //else 30                 //{ 31                 //    using (FileStream fs = new FileStream("~/File/2.txt", FileMode.Create, FileAccess.Write, FileShare.Write)) 32                 //    { 33                 //        string msg = postStr; 34                 //        byte[] bytes = System.Text.Encoding.Default.GetBytes(msg); 35                 //        fs.Write(bytes, 0, bytes.Length); 36                 //    }   37                 //} 38             } 39         } 40         private void Valid() 41         { 42             string echoStr = Request.QueryString["echoStr"].ToString(); 43             if (CheckSignature()) 44             { 45                 if (!string.IsNullOrEmpty(echoStr)) 46                 { 47                     Response.Write(echoStr); 48                     Response.End(); 49                 } 50             } 51         } 52  53         /// <summary> 54         /// 验证微信签名 55         /// </summary> 56         /// <returns></returns> 57         private bool CheckSignature() 58         { 59             string signature = Request.QueryString["signature"].ToString(); 60             string timestamp = Request.QueryString["timestamp"].ToString(); 61             string nonce = Request.QueryString["nonce"].ToString(); 62             string[] ArrTmp = { Token, timestamp, nonce }; 63             Array.Sort(ArrTmp);//字典排序 64             string tmpStr = string.Join("", ArrTmp); 65             tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");//对该字符串进行sha1加密 66             tmpStr = tmpStr.ToLower();//对字符串中的字母部分进行小写转换,非字母字符不作处理 67             //WriteLog(tmpStr, Server);//计入日志 68             if (tmpStr == signature)//开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。开发者通过检验signature对请求进行校验,若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,否则接入失败 69             { 70                 return true; 71             } 72             else 73                 return false; 74         } 75  76         /// <summary> 77         /// 获取post返回来的数据 78         /// </summary> 79         /// <returns></returns> 80         private string PostInput() 81         { 82             Stream s = System.Web.HttpContext.Current.Request.InputStream; 83             byte[] b = new byte[s.Length]; 84             s.Read(b, 0, (int)s.Length); 85             return Encoding.UTF8.GetString(b); 86         } 87         /// <summary> 88         ///返回微信信息结果 89         /// </summary> 90         /// <param name="weixinXML"></param> 91         //private void ResponseMsg(string weixinXML) 92         //{ 93         //    try 94         //    { 95         //        XmlDocument doc = new XmlDocument(); 96         //        doc.LoadXml(weixinXML);//读取XML字符串 97         //        XmlElement rootElement = doc.DocumentElement; 98  99         //        XmlNode MsgType = rootElement.SelectSingleNode("MsgType");//获取字符串中的消息类型100 101         //        string resxml = "";102         //        if (MsgType.InnerText == "text")//如果消息类型为文本消息103         //        {104         //            var model = new105         //            {106         //                ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText,107         //                FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText,108         //                CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText,109         //                MsgType = MsgType.InnerText,110         //                Content = rootElement.SelectSingleNode("Content").InnerText,111         //                MsgId = rootElement.SelectSingleNode("MsgId").InnerText112         //            };113         //            resxml += "<xml><ToUserName><![CDATA[" + model.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + model.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime>";114         //            if (!string.IsNullOrEmpty(model.Content))//如果接收到消息115         //            {116         //                if (model.Content.Contains(" 你好") || model.Content.Contains(" 好") || model.Content.Contains("hi") || model.Content.Contains("hello"))// 你好117         //                {118         //                    resxml += "<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[你好,有事请留言,偶会及时回复你的。]]></Content><FuncFlag>0</FuncFlag></xml>";119         //                }120 121         //            }122 123         //            else//没有接收到消息124         //            {125         //                resxml += "<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[亲,感谢您对我的关注,有事请留言。]]></Content><FuncFlag>0</FuncFlag></xml>";126         //            }127 128         //            Response.Write(resxml);129         //        }130         //        if (MsgType.InnerText == "image")//如果消息类型为图片消息131         //        {132         //            var model = new133         //            {134         //                ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText,135         //                FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText,136         //                CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText,137         //                MsgType = MsgType.InnerText,138         //                PicUrl = rootElement.SelectSingleNode("PicUrl").InnerText,139         //                MsgId = rootElement.SelectSingleNode("MsgId").InnerText140         //            };141         //            resxml += "<xml><ToUserName><![CDATA[" + model.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + model.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[news]]></MsgType><ArticleCount>1</ArticleCount><Articles><item><Title><![CDATA[欢迎您的光临!]]></Title><Description><![CDATA[非常感谢您的关注!]]></Description><PicUrl><![CDATA[http://...jpg]]></PicUrl><Url><![CDATA[http://www.baidu.com/]]></Url></item></Articles><FuncFlag>0</FuncFlag></xml>";142         //            Response.Write(resxml);143         //        }144         //        else//如果是其余的消息类型145         //        {146         //            var model = new147         //            {148         //                ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText,149         //                FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText,150         //                CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText,151         //            };152         //            resxml += "<xml><ToUserName><![CDATA[" + model.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + model.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[亲,感谢您对我的关注,有事请留言,我会及时回复你的哦。]]></Content><FuncFlag>0</FuncFlag></xml>";153         //            Response.Write(resxml);154         //        }155         //    }156         //    catch (Exception ex)157         //    {158         //        throw ex;159         //    }160         //    Response.End();161         //}162         /// <summary>163         /// datetime转换成unixtime164         /// </summary>165         /// <param name="time"></param>166         /// <returns></returns>167         private int ConvertDateTimeInt(System.DateTime time)168         {169             System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));170             return (int)(time - startTime).TotalSeconds;171         }172         /// <summary>173         /// 写日志(用于跟踪),可以将想打印出的内容计入一个文本文件里面,便于测试174         /// </summary>175         //public static void WriteLog(string strMemo, HttpServerUtility server)176         //{177         //    string filename = server.MapPath("/logs/log.txt");//在网站项目中建立一个文件夹命名logs(然后在文件夹中随便建立一个web页面文件,避免网站在发布到服务器之后看不到预定文件)178         //    if (!Directory.Exists(server.MapPath("//logs//")))179         //        Directory.CreateDirectory("//logs//");180         //    StreamWriter sr = null;181         //    try182         //    {183         //        if (!File.Exists(filename))184         //        {185         //            sr = File.CreateText(filename);186         //        }187         //        else188         //        {189         //            sr = File.AppendText(filename);190         //        }191         //        sr.WriteLine(strMemo);192         //    }193         //    catch194         //    {195         //    }196         //    finally197         //    {198         //        if (sr != null)199         //            sr.Close();200         //    }201         //}202     }203 }
View Code

看到源码那个Token了吧,大家知道作用了吧。这个是成功后的界面,我用的测试账户,而不是正式的,正式的申请太麻烦,时间很长

到此你就成为开发者了,接下来最重要的是会话界面自定义菜单 这个不难。

我使用微信的  微信公众平台接口调试工具演示的,在会话界面自定义菜单之前你需要获得access_token

 

点击检查问题,你会获得access_token。

现在知道上面的access_token的用处了吧

根据官方创建菜单API就可以创建菜单了 这个其实是不难的。文档很详细。

下面介绍获得用户的openid  (这个和获得用户信息是一样的)

openid每个微信账户是唯一的,这个可以作为你项目中关联用户信息的外键

我的需求是每次用户点击菜单获得该微信账户的openid,然后关联用户信息,

直接贴代码 这里的appid是你成为开发者的时候微信分配的

using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Web;using System.Web.Mvc;using System.Web.Script;using System.Web.Script.Serialization;using SCKY.WebApp.Models;using SCKY.Model;using SCKY.BLL;using SCKY.Commons;namespace SCKY.WebApp.Controllers{    public class TestController : Controller    {        //        // GET: /Test/        public ActionResult Index()        {            String code = Request["code"];//我们要的code            //code = "0048aa3c358df7ef9ef4f7df7ee3c57b";            string url = Request["state"];            var client = new WebClient();            string str = client.DownloadString("https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appid+"&secret="+secret+"&code=" + code + "&grant_type=authorization_code");            //client.DownloadString(new Uri(str));            Oppid oppided = new Oppid();            JavaScriptSerializer jss = new JavaScriptSerializer();            oppided = jss.Deserialize<Oppid>(str);            Session["Oppid"] = oppided.openid;            UCML_UserManager userBll = new UCML_UserManager();            UCML_User user = userBll.LoadEntities(d => d.UserEmail == oppided.openid && d.TelNumber == "2").FirstOrDefault();            if (user != null)            {                Session["UserOID"] = user.UCML_UserOID;                url = JudgeShipperPage(user, url);                return Redirect(url);            }            else            {                return RedirectToAction("NotUser", "Test", new { rowl = "2" });            }        }
View Code

这样你就得修改你的自定义菜单的代码了,直接贴上

{    "button": [        {            "type": "view",             "name": "托运发布",             "url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://www.CeShi.com/Test/Index&response_type=code&scope=snsapi_base&state=http://www.CeShi.com/ReleaseNews/Indx#wechat_redirect"        },         {            "type": "view",             "name": "选择车队",             "url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://www.CeShi.com/Test/Index&response_type=code&scope=snsapi_base&state=http://www.CeShi.com/NewsManager/Index#wechat_redirect"        },         {            "type": "view",             "name": "任务监控",             "url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://www.CeShi.com/Test/Index&response_type=code&scope=snsapi_base&state=http://www.CeShi.com/ShipperMonitoringManager/Index#wechat_redirect"        }    ]    }
View Code

上面涉及我的appid我都做了处理,读者注意了。

到此成为开发者,自定义菜单,获得openid就结束了,基本上是傻瓜流程了,不善于写博,请见谅