zoukankan      html  css  js  c++  java
  • .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 = new
    105         //            {
    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").InnerText
    112         //            };
    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 = new
    133         //            {
    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").InnerText
    140         //            };
    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 = new
    147         //            {
    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转换成unixtime
    164         /// </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         //    try
    182         //    {
    183         //        if (!File.Exists(filename))
    184         //        {
    185         //            sr = File.CreateText(filename);
    186         //        }
    187         //        else
    188         //        {
    189         //            sr = File.AppendText(filename);
    190         //        }
    191         //        sr.WriteLine(strMemo);
    192         //    }
    193         //    catch
    194         //    {
    195         //    }
    196         //    finally
    197         //    {
    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就结束了,基本上是傻瓜流程了,不善于写博,请见谅

  • 相关阅读:
    十个利用矩阵乘法解决的经典题目
    POJ-3070-Fibonacci
    java 正则表达式-忽略大小写与多行匹配
    【MM 非生产性物资采购】SAP实施项目中采购员在非生产性采购申请审批流中的角色安排(转)
    业务调研杂谈(转)
    重置报表输出选择
    【MM 配额管理】Quota Arrangement 配额管理(二)
    【MM 配额管理】Quota Arrangement 配额管理
    SDUST第十一次oj作业液晶显示问题
    如何在js代码中调用java,并将js的变量赋值给java
  • 原文地址:https://www.cnblogs.com/xiaolei1314/p/3864173.html
Copyright © 2011-2022 走看看