直接进入主题:
微信公众号开发文档,官方版(https://mp.weixin.qq.com/wiki),相信我,我已经吐不出写这个文档的人了。我真的很想把这个键盘剁了,但是开始之后发现是我自己掏钱买的。尴尬。
别瞎说,就说怎么部署,怎么发展。
首先你要有一个公共平台账号。好了,开始数坑。
第一个坑,不要以为没有企业号就发展不起来。申请考号的接口比所谓的订单号多。
进入后台管理后,点击开发者工具,可以看到公共平台测试账号,直接进入。开始填写您自己的配置。
注意涂鸦,这是程序中必须配置的东西。如果没有配置,将不会成功。
第二个坑,当然你的配置肯定不成功,所以别问我为什么。我没有图片可说。
请不要以为企鹅只是为了好玩。这是真的。肯定是80号口。其实只是一个发布域名的网站。因为有域名的网站都是80端口的,继续说正事吧。
企鹅告诉我们,要使用微信账号,必须有服务器,然后配置我们发布的网站。请注意,令牌是我们自己设置的,不是自动生成的。网址是我们发布的网站的名称
第三个坑,网站不发布,界面配置信息永远无法配置。记住,这是永远的。
JS接口安全域名,请直接参考文档(http://MP . weixin . QQ.com/wiki/7/AAA 137 b 55 FB 2e 0456 BF 8dd 9148 DD 613 f . html)。
JS界面安全域名的目的是下载图片,调用微信图片界面等。比如需要调用摄像头的时候,或者需要上传照片的时候,此时就需要JS安全接口。具体内容暂不详述。
在微信公众号测试号的版本背景中,体验界面权限表中的此项也必须配置。不需要配置,但是这个界面可以获取微信用户的一些信息。值得提醒的是,每个公众账号对应的每个ID都是唯一的,也就是说,即使网站的内网保持不变,如果微信官方账号发生变化,此时微信微信官方账号的数据是不能共享的,而只是相对于公众号是唯一的。
第四个坑,申请微信网页授权时,这里的网页对用户的基本信息进行了授权,本身没问题,但是有问题没有提示。
请注意这里的URL不包含www,后面也没有反斜杠,也就是说这里URL的回调格式是abc.com OK,请记住这个格式,一定要这样做。好了,服务器暂时是这样的,暂时开始用代码说话。
让我们从服务器身份验证开始。这是官网上的一个例子,不过是PHP。其实说白了,首先要验证一个随机数,然后在POST的情况下,检查返回值。直接编码
公共操作结果索引(){如果(请求.HttpMethod。ToLower()==' post '){ if(CheckSignature())//验证服务器是否通过{ GetMenulist();//加载菜单} else { Response .写(' h1Oh/h1h2我们相遇在火星吧!/H2 ';回应end();} }其他{检查微信();}返回视图();} ///摘要///返回随机数表示验证成功////汇总私人作废支票微信(){ if (string .IsNullOrEmpty(请求查询字符串[' echoStr '])){响应.写('消息并非来自微信');回应end();}字符串echoStr=请求查询字符串[' echoStr '];if (CheckSignature()) { Response .write(echoStr);回应end();} }///摘要///验证微信签名////summary////returns/returns//将令牌、时间戳、随机数三个参数进行字典序排序///将三个参数字符串拼接成一个字符串进行sha1加密///开发者获得加密后的字符串可与签名对比,标识该请求来源于微信私有bool CheckSignature(){ 0字符串签名=转换.ToString(请求['签名']);字符串时间戳=转换. ToString(请求['时间戳']);字符串随机数=转换. ToString(请求[' nonce ']);字符串[] ArrTmp={ Token,时间戳,nonce };数组排序(ArrTMp);//字典排序字符串tmpStr=字符串. Join(',' ArrTmp);tmpStr=FormsAuthentication .hashpasswordsforstoringconfigfile(tmpStr,' SHA1 ');tmpStr=tmpStr .toLower();if (tmpStr==签名){ 0返回true}否则{返回false} }然后,公众平台在有权限的情况下是自定义菜单的,但是一旦开始自定义菜单,原来的手动编辑的菜单是不能用的,也就是说,如果服务器验证通过,那么必须用自己的代码控制。
我们一起来看GetMenuList()这个方法,这个其实很简单的,就是随便凭借一个JSON格式字符串。然后调用微信的接口即可public void GetMenuList()
em id=' _ _ McEdel ' { string Wei in1=';weixin1=@ ' { '按钮'' :[ { '键入'' : ' '单击' ',' '名称' ' : ' '你好!',''键'' : ''你好' ' },{ ' '类型' ' : ' '视图' ',' '名称' ' : ' '公司简介,'网址' ' : ' ' http://www。xnfhtech。com ' ' },名称为' ' : ' '产品介绍,' ' sub_button'':[ { ' '键入' ' : ' '单击' ',' '名称' ' : ' '产品1 '',''键' :''p1'' },{ ' '类型' ' : ' '单击' ',' '名称' ' : ' '产品2 ' ',' key ' ' : ' ' p2 ' ' }]}]} ';字符串访问_令牌=工具WA_GetAccess_Token .IsExistAccess _ Token();字符串i=这个菜单创建(菜单,access _ token);回应。书写;}brbr/em公共字符串MenuCreate(string MenuJson,string access _ token){ JAVAScript Serializer Js=new JAVAScript Serializer();字符串setMenuUrl='https://api.weixin.qq.com/cgi-bin/menu/create?access _ token={ 0 } ';setMenuUrl=字符串。格式(setMenuUrl,access _ token);//获取令牌、拼凑全球资源定位器(Uniform Resource Locator)字符串resp text=webrequestpost outter(setMenuUrl,MenuJson);Dictionarystring,object resp DIC=(字典字符串,对象)Jss .反序列化对象;返回respDic['errcode'].ToString();//返回0发布成功} ///summary ///Post/get提交调用抓取////summary ///param name='url '提交地址/param ///param名称='param '参数/param///返回string/返回公共字符串WebRequestPostOrGet忘记(字符串sUrl,字符串sParam) { byte[] bt=System .文字。编码。utf8。get bytes(sParam);uriurl=新的URi(SurL);Httpwebrequest=(Httpwebrequest)Httpwebrequest .创建uri(网址);//Httpwebrequest=(Httpwebrequest)Httpwebrequest .创建(网址的索引('?') -1 ?'' : '?')参数);请求。方法='发布请求。超时=120 * 1000;请求内容类型=' application/x-www-form-URL编码;请求ContentLength=bt .长度;使用(流请求流=请求. getrequest stream())//使用使用可以释放使用段内的内存{ reqStream .写(bt,0,bt .长度);请求流flush();}尝试{使用(网络响应资源=请求.GetResponse()) { //在这里对接收到的页面内容进行处理stream=RES . GetResponsesStream();StreamReader resStreamReader=新的流阅读器(流,系统.文字。编码。utf8);字符串resLine系统。字符串生成器=新系统文本。StringBuilder();while ((resLine=resStreamReader .ReadLine())!=null) { resStringBuilder .追加(重新排队系统环境。NewLine);} resStream .close();resStreamReader .close();返回resStringBuilder .ToString();} } catch (Exception ex) { return ex .消息;//url错误时候回报错} }好吧,我承认我是一个不明真相的吃货,怎么又多了一个access _ Token=is exist access _ Token();呢,莫着急,宝宝告诉你。
当我们阅读文档的时候,我们会发现,这里的访问_令牌是每两个小时就过期的。这里的方法就是让他过期的时候自动获取。
第五坑,这里的JSON字符串,也就是要展示的菜单,我希望大家都用小写,如果用了大写,那么,呵呵,哈哈了真心的,很操蛋的,他会告诉你没有用UTF8编码,但是你真心是编码过的,可惜还是出错,所以,还是小写吧,唉
继续说两个小时自动获取之后,就是通过菜单创建(调用微信菜单接口)输出即可。上代码。
///摘要///防止每次请求的代币两个小时的变化////summarypublic类WA _ GetACCESS _ Token { public WA _ GetACCESS _ Token()} { public static WAentity .access _ Token GetACCESS _ Token(){ 0字符串网址='https://api.weixin.qq.com/cgi-bin/token?grant _ type=client _ credential appid='配置管理器.AppSettings[' AppID ']' secret='配置管理器.AppSettings[' AppSecret '];访问令牌实体=新access _ token();请尝试{ Httpwebrequest=(Httpwebrequest)Httpwebrequest .创建(网址);请求。方法=' GET '使用(网络响应wr=req .GetResponse()){ Httpwebresponse my response=(Httpwebresponse)req .GetResponse();流阅读器=新流阅读器(MyResponse .GetResponseStream(),系统文本。编码。utf8);字符串内容=阅读器ReadToEnd();Access _ token=新的access _ token();token=JsonHelper .ParseFromJsonAccess _ token(内容);实体。access _ token=令牌。access _ token实体。expires _ in=令牌。expires _ in} } catch{ //记录日志}返回实体;} ///摘要///根据当前日期判断访问_令牌是否超期如果超期返回新的访问_令牌否则返回之前的access _ Token////summary///param name=' datetime '/param///returns/returns公共静态字符串isexist access _ Token(){ try { string Token=string .空的;DateTime YouXRQ//读取可扩展置标语言文件中的数据,并显示出来字符串文件路径=HttpContext .当前。请求。mappath(' ~/xmlfile。XML ');流阅读器字符串=新的流阅读器(文件路径,系统文本。编码。utf8);XML文档XML=新建XML文档();xml .加载(字符串);字符串close();字符串dispose();Token=xml .选择单个节点(“xml”).选择单个节点("访问令牌")。InnerTextYouXRQ=转换今日时间.选择单个节点(“xml”).选择单个节点(' Access_YouXRQ ').InnerText);if (DateTime .现在YouXRQ){ DateTime _ YouXRQ=DateTime .现在;WAEntity .访问令牌模式=GetACCESS _ Token();xml .选择单个节点(“xml”).选择单个节点("访问令牌")。inner text=mode . access _ token _ youxrq=_ youxrq .添加秒(转换.至t32(模式。expires _ in));xml .选择单个节点(“xml”).选择单个节点(' Access_YouXRQ ').InnerText=_youxrq .ToString();xml .保存(文件路径);Token=mode.access _ token}返回令牌}捕获(异常ex){返回" ";//记录日志} }}公共类Access _ token { public Access _ token(){ }公共字符串access _ token { get设置;}公共字符串在{ get设置;}}公共类JsonHelper{ ///summary ///生成Json格式////summary///type param name=' T '/type param///param name=' obj '/param///returns/returns公共静态字符串GetJsonT(T obj){ DataContractJsonSerializer JSON=new DataContractJsonSerializer(obj .GetType());使用(内存流流=new MemoryStream()) { json .WriteObject(stream,obj);字符串szJson=编码. UTF8。GetString(流. to array());返回sjson } }///摘要///获取Json的model////summary///type param name=' T '/type param///param name=' szJson '/param//返回/返回公共静态T ParseFromJsonT(字符串sjson){ T obj=Activator .create instance cet();使用(MemoryStream ms=new MemoryStream(编码. UTF8。GetBytes(sjson)){ DataContractJsonSerializer序列化程序=new DataContractJsonSerializer(obj .GetType());返回(吨)序列化程序ReadObject(毫秒);} }}原谅我又不明真相了,所谓的XMLFile.xml这又是什么鬼,好吧,我其实不想说的这么直白的,还是代码直接上比较好。
?可扩展标记语言版本='1.0 '编码='utf-8 '?可扩展标记语言访问令牌获取TOKEN/Access _ TOKEN Access _ YouXRQ 2015/9/12 17:56:31/Access _ YouXRQ/XML我确定这个你真心不想说什么了
好吧,默默的吃着瓜子,静静的看着你们继续,今天就先到这里,随后我们继续走起,已经五个坑了呀,宝宝心里苦呀。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。