c# 微信小程序B接口获取小程序二维码

一入微信,满地是坑,这个坑,你得一个个填过去。

 

产品要求用户通过其他用户的推荐二维码进入小程序,并且绑定二维码所带的参数

微信小程序的二维码生成分为A接口和B接口:

c# 微信小程序B接口获取小程序二维码_第1张图片

这是微信的官方文档介绍(文档链接如下https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/qr-code.html)

A接口上限是10W个,B接口没有上限

对于这个应用场景,我选择了B接口生成小程序码

 

首先我们要获取到申请接口所有用的assess_token(附上官方文档https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html)

通过GET请求到access_token,因为我们前端、API、后台都需要用到access_token,所以是将其产生时间和token保存在数据库中

public static AccessToken GetACCESS_TOKEN(AccessToken model)
        {
            try
            {
                //token 使用时效为2小时, 5分钟的过期时间是前后两个都能用
                if (model.access_token_time.AddSeconds(model.expires_in - 5) > DateTime.Now)
                {
                    return model;
                }

                #region 调用 ACCESS_TOKEN 接口
                //拼接URL
                string url = "https://api.weixin.qq.com/cgi-bin/token";
                url += "?grant_type=client_credential";
                url += "&appid=" + WxConfig.APPID;//小程序APPID
                url += "&secret=" + WxConfig.APPSECRET;//小程序APPSECRET
                Uri address = new Uri(url);
                HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
                request.Method = "GET";
                request.ContentType = "application/x-www-form-urlencoded";
                request.Timeout = 6000;

                #endregion

                #region 反馈

                using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                {
                    StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                    string retString = reader.ReadToEnd();
                    reader.Close();
                    JavaScriptSerializer _serializer = new JavaScriptSerializer();
                    AccessToken accessToken = _serializer.Deserialize(retString);
                    if (accessToken.access_token != null)
                    {
                        model.access_token = accessToken.access_token;
                        model.expires_in = accessToken.expires_in;
                        model.access_token_time = DateTime.Now;
                        model.Changed = true;
                        return model;
                    }
                }

                #endregion
            }
            catch (Exception e)
            {
                Log.Error("WxApi", "GetACCESS_TOKEN : " + e.Message);
            }

            return null;
        }

创建了UnlimitedQRCodeModel类

public class UnlimitedQRCodeModel
    {

        public string scene { get; set; }

        public string page { get; set; }
    }

并在功能模块进行小程序码获取、保存

AccessToken accessToken = _accessTokenService.GetFirst();
                    accessToken.Changed = false;
                    accessToken = WxApi.GetACCESS_TOKEN(accessToken);
                    if (accessToken != null && accessToken.access_token != null)
                    {
                        if (accessToken.Changed)
                        {
                            _accessTokenService.Update(accessToken);
                        }
                        //创建实例
                        UnlimitedQRCodeModel qrcodeModel = new UnlimitedQRCodeModel
                        {
                            page = "pages/mobile_add/mobile_add",
                            scene = "recommendId=" + model.Id
                        };
                        //微信请求小程序码的url
                        string url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken.access_token;
                        //转换为JSON字符串
                        JavaScriptSerializer jss = new JavaScriptSerializer();
                        string json = jss.Serialize(qrcodeModel);
                        //获取post返回的二进制流
                        byte[] response = HttpService.CreateQRCode(json, url, false, 6);
                        //将二进制流保存为png图片,返回保存路径
                        var filePath = UploadHelper.SavePng(response, imagePathPrefix);
                        if (filePath != null)
                        {
                            //业务代码
                        }
                    }
 public static byte[] CreateQRCode(string xml, string url, bool isUseCert, int timeout)
        {
            System.GC.Collect();//垃圾回收,回收没有正常关闭的http连接

            byte[] result = null;//返回结果

            HttpWebRequest request = null;
            HttpWebResponse response = null;
            Stream reqStream = null;

            try
            {
                //设置最大连接数
                ServicePointManager.DefaultConnectionLimit = 200;
                //设置https验证方式
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    ServicePointManager.ServerCertificateValidationCallback =
                            new RemoteCertificateValidationCallback(CheckValidationResult);
                }

                /***************************************************************
                * 下面设置HttpWebRequest的相关属性
                * ************************************************************/
                request = (HttpWebRequest)WebRequest.Create(url);

                request.Method = "POST";
                request.Timeout = timeout * 1000;

                //设置POST的数据类型和长度
                request.ContentType = "text/xml";
                byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);
                request.ContentLength = data.Length;

                //是否使用证书
                if (isUseCert)
                {
                    string path = HttpContext.Current.Request.PhysicalApplicationPath;
                    X509Certificate2 cert = new X509Certificate2(path + WxConfig.SSLCERT_PATH, WxConfig.SSLCERT_PASSWORD);
                    request.ClientCertificates.Add(cert);
                    Log.Debug("WxPayApi", "PostXml used cert");
                }

                //往服务器写入数据
                reqStream = request.GetRequestStream();
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();

                //获取服务端返回
                response = (HttpWebResponse)request.GetResponse();

                //获取服务端返回数据
                Stream sr = response.GetResponseStream();
                result = StreamToBytes(sr);
                if (sr != null) sr.Close();
            }
            catch (System.Threading.ThreadAbortException e)
            {
                System.Threading.Thread.ResetAbort();
            }
            catch (WebException e)
            {

                throw new WxPayException(e.ToString());
            }
            catch (Exception e)
            {
                throw new WxPayException(e.ToString());
            }
            finally
            {
                //关闭连接和流
                if (response != null)
                {
                    response.Close();
                }
                if (request != null)
                {
                    request.Abort();
                }
            }
            return result;
        }
public static string SavePng(byte[] file, string filePath)
        {
            try
            {
                var appPath = GetAppPath();
                appPath += filePath;
                if (!Directory.Exists(appPath))
                {
                    DirectoryInfo dir = new DirectoryInfo(appPath);
                    dir.Create();
                }
                var fileName = Guid.NewGuid().ToString("N") + ".png";
                File.WriteAllBytes(Path.Combine(appPath, fileName), file);

                return filePath + "/" + fileName;
            }
            catch
            {
                return null;
            }
        }

至此小程序码获取成功了,也保存到了对应路径。

 

注意!!!以下问题

小程序必须是通过审核的!

二维码的页面路径必须是已经发布的

在使用B接口的时候PAGE参数不要带参数,参数需要存放在scene中

记得!记得!记得!在小程序后台开发设置里面配置链接二维码打开小程序!!

 

在这过程中,碰到了一个很坑的问题,发现保存的图片都是异常、无法打开的。

在官方文档里请求参数里加了access_token,一开始也疑惑,明明URL上带了,为什么请求里还有加,以为是微信的要求。但是在UnlimitedQRCodeModel实例中加入access_token参数的时候,怎么请求都是错误的数据。百度发现这个参数是多余的!!多余的!!多余的!!是不需要的,不加这个就好了。

c# 微信小程序B接口获取小程序二维码_第2张图片

 

最后最后!还是想到之前走的那个人说,一入小程序,放眼望去,全是坑!!!!!!不对!!!一入微信全是坑,公众号那玩意儿也是!!!

你可能感兴趣的:(微信小程序,c#,微信小程序)