Five pitfalls before php public account development (1): Public
Direct topic:
Public Account development documentation, official version (https://mp.weixin.qq.com/wiki), believe me, I have been unable to speak to write this document, I really want to crack this keyboard, but after the start to find, I used to pay for the keyboard myself .... Embarrassed.
Let alone how to deploy and develop.
First, you have to have a public platform account.
First pitfall,Do not think that development is not allowed if it is not an enterprise number. You can apply for a test number, which is more than the so-called subscription number interface.
After entering the background management, click the developer tool to view the public platform test account and go directly to the console. Enter your own configuration.
Note the graffiti part. This part must be configured in the program. If it is not configured, it will not succeed.
Pitfall 2Of course, your configuration will fail. Don't ask me why. No picture...
Please do not think that emperor penguin is playing. This is true. It must be port 80. In fact, a website with a domain name can be published. Because all websites with domain names come out of port 80, let's continue with the question.
Emperor Penguin told us that to use an account, we must have a server and then configure the website we released. Please note that the token is set by yourself. This is not automatically generated, set it by yourself .. The URL is the name of the website we published.
Third pitfall,If the website is not published, the interface configuration information is never configured. Remember, it is always.
JS interface Security Domain Name, please refer directly to the document (http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html ).
The JS interface security domain name is designed to download images and call image interfaces. For example, when you need to call a camera or upload a photo, at this time, the JS security interface is required. The specific content is not described in detail at the moment.
In the version background of the Public Account test number, this item in the user experience interface permission table is also required. It is not necessarily configured, but this interface can obtain part of the user's information. It is worth noting that each ID corresponding to each public account is unique. That is to say, even if the Intranet of the website remains unchanged, if the public number is changed, at this time, the data of the public account cannot be in common, but it is only relative to the public account.
Fourth pitfall,When applying for webpage authorization, there is no problem with the basic information of the webpage authorized users, but there is no prompt.
Note the following URL,It must not contain www, and there is no backslash behind it.That is to say, the callback format of the URL here is abc.com OK. Remember this format and you must do this. Now, the server is talking with code.
Start with server verification. This is an example on the official website, but it is PHP. To put it bluntly, we should first verify a random number and then check the return value in the case of POST. Directly Add code
Public ActionResult Index () {if (Request. httpMethod. toLower () = "post") {if (CheckSignature () // verify whether the server passes {GetMenuList (); // load menu} else {Response. write ("
Then, the public platform uses custom menus with permissions. However, once a custom menu is started, the original manually edited menu cannot be used. That is to say, if the server passes verification, you must use your own code.
Let's take a look at the GetMenuList () method, which is actually very simple, that is, simply relying on a JSON string. Then you can call the interface. Public void GetMenuList ()
<Em id = "_ mceDel"> {string weixin1 = ""; weixin1 = @ "{" "button" ": [{" "type "": "" click "", "" name "": "" Hello! "", "" Key ":" "hello" "},{" "type": "" view "", "" name "": "" Company Profile "", "" url ":" "http://www.xnfhtech.com" "},{" "name": "Product Introduction" "," "sub_button "": [{"" type ":" "click" "," "name": "" Product 1 "", "" key ":" p1 ""}, {"" type ":" "click" "," "name": "" product 2 "", "" key "": "" p2 ""}]} "; string access_token = Tools. WA_GetAccess_Token.IsExistAccess_Token (); string I = this. menuCreate (menu, access_token); Response. write (I) ;}< br> </em>
Public string MenuCreate (string MenuJson, string access_token) {JavaScriptSerializer Jss = new JavaScriptSerializer (); string setMenuUrl = "https://api.weixin.qq.com/cgi-bin/menu/create? Access_token = {0} "; setMenuUrl = string. format (setMenuUrl, access_token); // get token and splice url string respText = WebRequestPostOrGet (setMenuUrl, MenuJson); Dictionary <string, object> respDic = (Dictionary <string, object>) jss. deserializeObject (respText); return respDic ["errcode"]. toString (); // return 0 successfully released} // <summary> // Post/get submit call capture // </summary> /// <param name = "url"> submit address </param> /// <param name = "para M "> parameter </param> /// <returns> string </returns> public string WebRequestPostOrGet (string sUrl, string sParam) {byte [] bt = System. text. encoding. UTF8.GetBytes (sParam); Uri uriurl = new Uri (sUrl); HttpWebRequest req = (HttpWebRequest) HttpWebRequest. create (uriurl); // HttpWebRequest req = (HttpWebRequest) HttpWebRequest. create (url + (url. indexOf ("? ")>-1? "":"? ") + Param); req. method = "Post"; req. timeout = 120*1000; req. contentType = "application/x-www-form-urlencoded;"; req. contentLength = bt. length; using (Stream reqStream = req. getRequestStream () // using can be used to release memory {reqStream. write (bt, 0, bt. length); reqStream. flush ();} try {using (WebResponse res = req. getResponse () {// process the received page content Stream resStream = res. getResponseStream (); StreamR Eader resStreamReader = new StreamReader (resStream, System. text. encoding. UTF8); string resLine; System. text. stringBuilder resStringBuilder = new System. text. stringBuilder (); while (resLine = resStreamReader. readLine ())! = Null) {resStringBuilder. append (resLine + System. environment. newLine);} resStream. close (); resStreamReader. close (); return resStringBuilder. toString () ;}} catch (Exception ex) {return ex. message; // return an error when a url error occurs }}
Well, I admit that I am a fool with unknown truth. Why is there an additional access_token = IsExistAccess_Token ()? Don't worry, please let me know.
When reading the document, we will find that the Access_Token here expires every two hours. The method here is to automatically obtain it when it expires.
Fifth pitfallHere, the JSON string, that is, the menu to be displayed, I hope everyone will use lower-case letters. If it is used in upper-case letters, then, haha, haha, really, really cool, he will tell you that UTF8 encoding is not used, but you have actually coded it, but it is a pity that it is still wrong, so it should be in lower case, alas
After two hours of Automatic Acquisition, you can use MenuCreate (call the menu interface) to output the data. On the code.
/// <Summary> /// prevents the token of each request from changing for two hours /// </summary> public class WA_GetAccess_Token {public WA_GetAccess_Token () {} public static WAEntity. access_token GetAccess_Token () {string url = "https://api.weixin.qq.com/cgi-bin/token? Grant_type = client_credential & appid = "+ ConfigurationManager. appSettings ["AppID"] + "& secret =" + ConfigurationManager. deletetoken ["AppSecret"]; Access_token entity = new Access_token (); try {HttpWebRequest req = (HttpWebRequest) HttpWebRequest. create (url); req. method = "GET"; using (WebResponse wr = req. getResponse () {HttpWebResponse myResponse = (HttpWebResponse) req. getResponse (); StreamReader read Er = new StreamReader (myResponse. getResponseStream (), System. text. encoding. UTF8); string content = reader. readToEnd (); Access_token token = new Access_token (); token = JsonHelper. parseFromJson <Access_token> (content); entity. access_token = token. access_token; entity. expires_in = token. expires_in ;}} catch {// record log} return entity;} // <summary> // determine whether the Access_Token is out of date based on the current date. If the new Access_Token is returned Returns the previous Access_Token /// </summary> /// <param name = "datetime"> </param> /// <returns> </returns> public static string isExistAccess_Token () {try {string Token = string. empty; DateTime YouXRQ; // read data from the XML file and display string filepath = HttpContext. current. request. mapPath ("~ /XMLFile. xml "); StreamReader str = new StreamReader (filepath, System. text. encoding. UTF8); XmlDocument xml = new XmlDocument (); xml. load (str); str. close (); str. dispose (); Token = xml. selectSingleNode ("xml "). selectSingleNode ("Access_Token "). innerText; YouXRQ = Convert. toDateTime (xml. selectSingleNode ("xml "). selectSingleNode ("Access_YouXRQ "). innerText); if (DateTime. now> YouXRQ) {DateTime _ youxrq = DateTime. now; WAEntity. access_token mode = GetAccess_Token (); xml. selectSingleNode ("xml "). selectSingleNode ("Access_Token "). innerText = mode. access_token; _ youxrq = _ youxrq. addSeconds (Convert. toInt32 (mode. expires_in); xml. selectSingleNode ("xml "). selectSingleNode ("Access_YouXRQ "). innerText = _ youxrq. toString (); xml. save (filepath); Token = mode. access_token;} return Token;} catch (Exception ex) {return ""; // record logs} public class Access_token {public Access_token () {} public string access_token {get; set;} public string expires_in {get; set ;}} public class JsonHelper {// <summary> // generate Json format /// </summary> /// <typeparam name = "T"> </typeparam> // /<param name = "obj"> </param> // <returns> </returns> public static string GetJson <T> (T obj) {DataContractJsonSerializer json = new DataContractJsonSerializer (obj. getType (); using (MemoryStream stream = new MemoryStream () {json. writeObject (stream, obj); string szJson = Encoding. UTF8.GetString (stream. toArray (); return szJson ;}} /// <summary> /// obtain the Json Model /// </summary> /// <typeparam name = "T"> </typeparam> /// <param name = "szJson"> </param> // <returns> </returns> public static T ParseFromJson <T> (string szJson) {T obj = Activator. createInstance <T> (); using (MemoryStream MS = new MemoryStream (Encoding. UTF8.GetBytes (szJson) {DataContractJsonSerializer serializer = new DataContractJsonSerializer (obj. getType (); return (T) serializer. readObject (MS );}}}
Forgive me for not knowing the truth. What is the so-called XMLFile. xml? Well, I don't really want to say this straightforward, but it's better to directly use the code.
<? Xml version = "1.0" encoding = "UTF-8"?> <Xml> <Access_Token> Get TOKEN </Access_Token> <Access_YouXRQ> 17:56:31 </Access_YouXRQ> </xml>
I'm sure you really don't want to say anything.
All right, eat melon seeds silently and watch you continue. Let's go here today. Then we continue to go on. Five traps have been found, and the baby is bitter.
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.