微信公众号-入坑指南(一)

时间:2020-08-28 15:00:48   收藏:0   阅读:91

       微信公众号开发,没接触过的时候觉得挺高大上,自脱离大厂,入职中小公司后,技术几乎全靠自己一个人踩抗,当初入职公司的时候,第一个主任务中有一部分就涉及到了公众号开发,包括订阅,推送,学生扫码支付宿舍水电费,住宿费等等。由于从来没接触过微信开发,所以抱着无比激动的心情啃了一遍又一遍微信接口文档,不明就里。因为完全没有一点概念,首先要搞清楚订阅号,企业号,公众号三者之间的关系。区别还是挺大的,个人目前只能申请订阅号,微信提供的接口贼少,连个自定义菜单接口都么有,个人推推文章啥的凑合着用,要想尝试更多功能,只能是企业身份去注册公众号,当然有些功能还都是收费的,比如模板推送消息就要300元/年。其实网上很多教程代码给的都有坑,Copy下来很多都是自定义的类,又不提供全,很不利于新手的学习,新手最想的是什么,先来一个简单的,可以跑起来的程序,然后由浅及深的自我去认知,找个某系列教程, copy下来后 ,报红,一看是自定义类的锅,源码中又没有,真是坑,换一个教程,copy下来又是如此,反反复复几次,心态很容易就蹦,如果有接触过微信开发,或者能静下心来啃文档,这些都还好,当初我呢,时间很急,又从来没有接触过,身边更没有同事去请教,真是越慌越糟糕,最后一点一点的啃出来。只要程序能跑起来,心里大致有谱了,这个时间在去接触接口文档,看需求,加功能就得心应手了,万事开头难,古人诚不欺我也!

       第一.搞微信第一个坑,要有一个外网,这里是在花生壳上注册一个域名,要保证域名解析正常,不正常的及时到官网找原因,或者直接提交工单,让后台人员处理,毕竟免费的壳域名不稳定,收费的顶级域名果然稍微好点(现在域名需要实名认证),在域名解析正常之后,开始设置内网映射。注意这里内网主机的端口号设置为80,没办法微信规定只对接80 或者443(https),之前可以转接端口号后来被封了只能老老实实用80。如下图所示:                                                       

                       技术图片技术图片

 

 

 

      第二,外网映射的问题搞定后,意味已经拥有了自己的外网域名网站,就可以着手开发网站,自动回复消息,这里新建一 MVC空项目,在引用中下载微信negut 包,主要盛派的 Senparc.Weixin.MP,Senparc.Weixin.MP.MVC 两个包,然后新建一控制器WeChat,方法如下,这是方法是用来验证订阅号中相关参数配置是否正确,需要登录微信公众平台在基本参数里面配置时 ,这里填写 url 的一定要为外网,并且指向地址一定要是这里新建的控制器 Wechat 保持一致

        // GET: WeChat
        [HttpGet]
        [ActionName("Index")]
        public Task<ActionResult> Get(string signature, string timestamp, string nonce, string echostr)
        {
            return Task.Factory.StartNew(() =>
            {
//申请订阅号token
var token = ConfigHelper.ExitCache("Token"); if (CheckSignature.Check(signature, timestamp, nonce, token)) { //获取Token var acestoken = TokenHelper.IsExistAccess_Token(); return echostr; //返回随机字符串则表示验证通过 } else { return "failed:" + signature + "," + CheckSignature.GetSignature(timestamp, nonce, token) + "" + "如果你在浏览器中看到这句话,说明此地址可以被作为微信公众账号后台的Url,请注意保持Token一致。"; } }).ContinueWith<ActionResult>(task => Content(task.Result)); }

填写一致后,微信公众平台里保存配置时,才会跳转到上面那个方法,检查好token,appId 等参数是否配对,有时候由于网络原因需要多点击几次,才会跳转到上面的方法中,调用微信接口时,需要提供一个token,而这个token 请求的次数对于订阅号而言是有限的,也就2000次,请求完了就没有了,所以一般这里,获取token的时候,我们判断一下token是否过期(2小时有效期),若未过期就不去请求最新的 token,避免浪费资源,这里处理方式为在配置文件中添加两个字段,一个保存 token,一个记录当前到期时间。完整代码如下:

 public class TokenHelper
    {
        /// <summary>
        /// 根据当前日期 判断Access_Token 是否超期  如果超期返回新的Access_Token   否则返回之前的Access_Token
        /// </summary>
        /// <param name="datetime"></param>
        /// <returns></returns>
        public static  string IsExistAccess_Token()
        {
            string token = string.Empty;
            DateTime youXRQ;
            // 读取XML文件中的数据,并显示出来 ,注意文件路径
            string filepath = ConfigHelper.ExitCache("CurrentTokenPath");
            XElement xml = XElement.Load(filepath);
            token = xml.Descendants("Access_Token").FirstOrDefault().Value.ToString();
            youXRQ = Convert.ToDateTime(xml.Descendants("Access_YouXRQ").FirstOrDefault().Value.ToString());
            //判断当前 token 是否过期
            if (DateTime.Now > youXRQ)
            {
                DateTime _youxrq = DateTime.Now;
                Access_token mode = GetAccess_token();

                xml.Descendants("Access_Token").FirstOrDefault().Value = mode.access_token;
                _youxrq = _youxrq.AddSeconds(int.Parse(mode.expires_in));
                xml.Descendants("Access_YouXRQ").FirstOrDefault().Value= _youxrq.ToString();
                xml.Save(filepath);
                token = mode.access_token;

            }
            return token;
        }


        /// <summary>
        /// 获取Access_token
        /// </summary>
        /// <returns></returns>
        private static Access_token GetAccess_token()
        {
            var appid = ConfigHelper.ExitCache("AppId");
            var secret = ConfigHelper.ExitCache("AppSecret");

            string strUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret;
            Access_token mode = new Access_token();
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strUrl);  //用GET形式请求指定的地址 
            req.Method = "GET";

            using (WebResponse wr = req.GetResponse())
            {
                StreamReader reader = new StreamReader(wr.GetResponseStream(), Encoding.UTF8);
                string content = reader.ReadToEnd();
                reader.Close();
                reader.Dispose();

                //在这里对Access_token 赋值  
                Access_token token = new Access_token();
                token = JsonHelper.ParseFromJson<Access_token>(content);
                mode.access_token = token.access_token;
                mode.expires_in = token.expires_in;
            }
            return mode;
        }
    }

其中类 Access_token 包含两个类型为字符串的成员字段 access_token(获取到的凭证),expires_in(凭证有效时间,秒),到这里算是将 微信公众号 和 所开发的程序关联起来。切记:微信公众平台中的白名单中需要添加开发电脑的内网ip,否则获取不到token,会提示当前往网络不在白名单内。

 

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!