ASP.NET Core的Web页面调用微信的扫一扫、上传图片等功能
1.需求:客户要求能够移动端扫描二维码、一维码
2.条件:
1)注册一个微信服务号,使用微信服务号进行网页Web的使用,使用微信的服务号打开改链接。
2)配置微信服务号的APPID、APPSECRET、白名单、JS接口安全域名、业务域名、网页授权域名、链接等
3.代码:
1)引用(这里在Nuget中引用Senparc.Weixin和Senparc.WeixinMP)
2)ASP.NET Core记得需要对管道过滤器进行配置(Startup.cs)
public void ConfigureServices(IServiceCollection services) { //微信 services.AddSenparcGlobalServices(Configuration)//Senparc.CO2NET 全局注册 .AddSenparcWeixinServices(Configuration);//Senparc.CO2NET 注册(如果是要Senparc.Weixin SDK则添加) services.AddSession(); services.AddMemoryCache();//使用本地缓存必须添加 services.AddSenparcWeixinServices(Configuration); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env,IOptions<SenparcSetting> senparcSetting,IOptions<SenparcWeixinSetting> senparcWeixinSetting) { IRegisterService register = RegisterService.Start(senparcSetting.Value).UseSenparcGlobal();//启动CO2NET全局注册 register.UseSenparcWeixin(senparcWeixinSetting.Value,senparcSetting.Value);//微信群居注册 }
3)页面视图方法
#region 扫描 public IActionResult Scan() { try { string appid = string.Empty; string secret = string.Empty; string host = HttpContext.Request.Host.Value; //int Port = HttpContext.Request.Host.Port.Value; int Port = 443;//这里服务器那边获取不到(我们就只能指定端口了) string path = HttpContext.Request.Path;//.Path; appid = ConfigurationManager.AppSettings["Wx_APPID"]; secret = ConfigurationManager.AppSettings["Wx_APPSECRET"]; string SvrCode = "123"; string objStr = "", thisUrl = Port == 443 ? "https://" + host + path : "http://" + host + path; string nonce = ""; string timestamp = ""; string ticket = ""; var signature = ""; string userAgent = HttpContext.Request.Headers["User-Agent"]; if (userAgent.IndexOf("MicroMessenger") <= -1)//不是微信浏览器 { objStr = string.Format("{{\"appid\": \"{0}\"", appid); objStr += string.Format(",\"timestamp\":\"{0}\"", timestamp); objStr += string.Format(",\"nonce\": \"{0}\"", nonce); objStr += string.Format(",\"thisUrl\": \"{0}\"", thisUrl); objStr += string.Format(",\"signature\": \"{0}\"", signature); objStr += string.Format(",\"SvrCode\": \"{0}\"", SvrCode); objStr += string.Format("}}"); JObject objOpenid1 = JsonConvert.DeserializeObject<JObject>(objStr); return View(objOpenid1); } //if (!string.IsNullOrEmpty(fxUrl)) { thisUrl += "?fxUrl=" + fxUrl + "&id=" + id; } nonce = JSSDKHelper.GetNoncestr(); timestamp = JSSDKHelper.GetTimestamp(); ticket = JsApiTicketContainer.TryGetJsApiTicket(appid, secret); objStr = string.Format("{{\"appid\": \"{0}\"", appid); objStr += string.Format(",\"timestamp\":\"{0}\"", timestamp); objStr += string.Format(",\"nonce\": \"{0}\"", nonce); objStr += string.Format(",\"thisUrl\": \"{0}\"", thisUrl); JSSDKHelper jsHelper = new JSSDKHelper(); ////最后一个参数url,必须为当前的网址 signature = JSSDKHelper.GetSignature(ticket, nonce, timestamp, thisUrl); objStr += string.Format(",\"signature\": \"{0}\"", signature); objStr += string.Format(",\"SvrCode\": \"{0}\"", SvrCode); objStr += string.Format("}}"); JObject objOpenid = JsonConvert.DeserializeObject<JObject>(objStr); return View(objOpenid); } catch (Exception ex) { var errInfo = new { Code = "Fail", ErrInfo = ex.ToString() }; return View(errInfo); } } #endregion
4)页面代码
@{ ViewBag.Title = "DTCTS-Scan"; var Version_JsAndCss = CJ.Common.ConfigHelper.ConfigAppSettings("Version_JsAndCss"); var cjUrl = CJ.Common.ConfigHelper.ConfigAppSettings("CJUrl"); Layout = "_LayoutWX"; } <!--添加css--> @section style{ <link rel="stylesheet" href="@Url.Content("/Content/h5/css/style.css?" + Version_JsAndCss)"> <style type="text/css"> .page, body { background-color: #f8f8f8; } .foot_nav li img { width: 0.54rem; margin: 0.1rem auto 0.1rem } .foot_nav li span { font-size: 0.26rem; } .footNav_box { height: 1.2rem; } .foot_nav { padding: 0 0.6rem; } </style> } <!--添加js--> @section scripts{ <script src="~/scan/jweixin-1.4.0.js"></script> <script type="text/javascript"> var dataForWeixin = { appId: "@Model.appid", MsgImg: "@Model.fxImg", TLImg: "@Model.fxImg", url: "@Model.thisUrl", fxUrl: "@Model.fxUrl", timestamp: "@Model.timestamp", nonceStr: "@Model.nonce", signature: "@Model.signature", SvrCode: "@Model.SvrCode", jsApiList: ['chooseImage', 'uploadImage', 'getLocalImgData', 'scanQRCode'], fakeid: "", callback: function () { } }; </script> <script src="~/scan/wxset.js"></script> } <div class="wrapper"> <input type="hidden" id="CJUrl" value="@cjUrl" /> <div class="container" style="margin: 0; width: 100%;"> <!--预览div--> <div class="weui-gallery" id="divGallery"> <span class="weui-gallery__img" id="spanGalleryImg"></span> <div class="weui-gallery__opr"> <a href="javascript:" rel="external nofollow" class="weui-gallery__del"> <i class="weui-icon-delete weui-icon_gallery-delete"></i> </a> </div> </div> <div class="weui-gallery" id="divGallery1"> @*<span class="weui-gallery__img" id="spanGalleryImg1"></span>*@ <img class="weui-gallery__img" id="spanGalleryImg1" style="width:80%; position: absolute; left: 50%; top: 40%; transform: translate(-50%, -40%);" /> @*<img class="weui-gallery__img" id="spanGalleryImg1" style="width: 100%" />*@ <div class="weui-gallery__opr"> <a href="javascript:" rel="external nofollow" class="weui-gallery__del1"> <i class="weui-icon-delete weui-icon_gallery-delete"></i> </a> @* <a href="javascript:" rel="external nofollow" class="weui-gallery__del1" download="w3logo"> <i class="weui-icon-download weui-icon_gallery-delete"></i> </a>*@ </div> </div> <form id="form1"> <input type="hidden" id="Image" name="Image"> <div class="weui-cells weui-cells_form" style="margin-top: 0px;"> <div class="weui-cell"> <div class="weui-cell__bd"> <textarea class="weui-textarea" name="ppid" id="ppid" placeholder="" rows="1"></textarea> </div> <div style="width:3em" id="scan"> <img src="~/scan/scan.png" /> </div> </div> <div class="weui-cell"> <div class="weui-cell__bd"> <select id="ftype" class="weui-select"></select> </div> </div> </div> <div class="weui-cells weui-cells_form uploaderCustom" style="margin-top: 0px;"> <div class="weui-cell"> <div class="weui-cell__bd"> <div class="weui-uploader"> <div class="weui-uploader__hd"> <p class="weui-uploader__title" style="text-align: left">上传图片</p> <div class="weui-uploader__info"> <span id="spanFileCount">0</span>/9 </div> </div> <div class="weui-uploader__bd"> <ul class="weui-uploader__files" id="ulFiles"></ul> <div class="weui-uploader__input-box"> <div id="uploaderInput" class="weui-uploader__input"></div> </div> </div> </div> </div> </div> </div> <div class="weui-btn-area"> <a class="weui-btn weui-btn_primary" onclick="addMoment()" style="color: #FFFFFF;">上 传</a> </div> <div class="weui-uploader__bd"> <ul class="weui-uploader__files" id="ulFiles1"> @*<li class="weui-uploader__file" onclick=previewImage1(this) style="background-image:url('https://api.cj-service.com.cn/Image/LJJ/12_202008071111209627.jpg')"></li>*@ </ul> </div> <div class="weui-cell"> <div class="weui-cell__bd"> <textarea class="weui-textarea" id="txtMsg" placeholder="" rows="6"></textarea> </div> </div> </form> </div> </div> @Html.Partial("_footer")
5)JS
$(function () { $("#ppid").blur(function () { getImage(); }); $("#ftype").change(function () { getImage(); }); FastClick.attach(document.body); //pageInit(); }); /* 图片手动上传 */ var uploadCustomFileList = []; var uploadCount = 0; var uploadMax = 9; var uploadAlready = 0; var loading; var $gallery = $("#divGallery"); var $galleryImg = $("#spanGalleryImg"); var $gallery1 = $("#divGallery1"); var $galleryImg1 = $("#spanGalleryImg1"); var $currentImage; wx.config({ debug: false, appId: dataForWeixin.appId, timestamp:dataForWeixin.timestamp, nonceStr: dataForWeixin.nonceStr, signature: dataForWeixin.signature, jsApiList: [ // 所有要调用的 API 都要加到这个列表中 'chooseImage', 'uploadImage', 'getLocalImgData', 'previewImage', 'scanQRCode' ] }); // 这里是简单的调用,其余api请参考文档 $("#uploaderInput") .bind('click', function() { wx.chooseImage({ count: uploadMax - uploadCount, // 默认9 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 success: function(res) { var index = 0; upFile(index, res.localIds); $("#ulFiles li").attr("onclick", "previewImage(this);"); } }); }); $("#scan").bind('click', function () { debugger console.log("scanClick") wx.scanQRCode({ needResult:1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果, scanType: ["qrCode", "barCode","datamatrix"], // 可以指定扫二维码还是一维码,默认二者都有 success: function (res) { var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果 var i = result.indexOf(','); if (i!=-1) { result = result.substring(i + 1); } $("#ppid").val(result); //加载图片 getImage(); } }); }); function pageInit() { ajaxobj.initajax("/Apibasis/HandUp", "getPhotoCode", getPhotoCode, { SvrCode: '', uid: '{$CJ$}' }); } function getPhotoCode(data) { console.log(data); if (data.Code == "200") { var Data = data.Data; var html = ""; $.each(Data, function (i, v) { html +='<option value="' + v.FCode + '">' + v.FCodeName + '</option>' }); $("#ftype").html(html); } else { alertMessage(data.Msg, null); } } function upFile(index, serverIds) { wx.uploadImage({ localId: serverIds[index], // 需要上传的图片的本地ID,由chooseImage接口获得 isShowProgressTips: 1, // 默认为1,显示进度提示 success: function(res) { var serverId = res.serverId; if (window.__wxjs_is_wkwebview) { wx.getLocalImgData({ localId: serverIds[index], // 图片的localID success: function(res) { var localData = res.localData; // localData是图片的base64数据,可以用img标签显示 $('#ulFiles') .append('<li class="weui-uploader__file" onclick=previewImage(this) style="background-image:url(' + localData + ')" data-id="' + serverId + '"></li>'); } }); } else { $('#ulFiles') .append('<li class="weui-uploader__file" onclick=previewImage(this) style="background-image:url(' + serverIds[index] + ')" data-id="' + serverId + '"></li>'); } ++uploadCount; $('#spanFileCount').text(uploadCount); if (uploadCount >= uploadMax) { $('.weui-uploader__input-box').hide(); } if (index < serverIds.length) { index++; upFile(index, serverIds); } else { $(event).closest('.weui-cell').removeClass('weui-cell_warn'); } } }); } function previewImage(obj) { $gallery.fadeIn(100); $galleryImg.css("background-image", "url(" + $(obj).css("backgroundImage").replace('url(', '').replace(')', '') + ")"); $currentImage = $(obj); } function previewImage1(obj) { $gallery1.fadeIn(100); //$galleryImg1.css("background-image", "url(" + $(obj).css("backgroundImage").replace('url(', '').replace(')', '') + ")"); $galleryImg1.attr("src", $(obj).css("backgroundImage").replace('url("', '').replace('")', '')); //alert($galleryImg1.height() ); //alert($gallery1.height()); //if ($gallery1.height() - $galleryImg1.height() > 100) { // $galleryImg1.css("margin-top", ($galleryImg1.height() - $gallery1.height()) / 5); //} $currentImage1 = $(obj); //alert($galleryImg1.height()); //alert($gallery1.height()); } $("#spanGalleryImg").click(function () { $gallery.fadeOut(100); }); $("#spanGalleryImg1").click(function () { $gallery1.fadeOut(100); }); $(".weui-gallery__del") .click(function() { $currentImage.remove(); --uploadCount; $('#spanFileCount').text(uploadCount); if (uploadCount < uploadMax) { $('.weui-uploader__input-box').show(); } $gallery.fadeOut(100); }); $(".weui-gallery__del1 i.weui-icon-delete") .click(function () { var imageUrl = $currentImage1.css("backgroundImage").replace('url(', '').replace("')", ""); if (!confirm("确定将服务器的图片删除?")) { return; } ajaxobj.initajax("/Apibasis/HandUp", "delImage", function (data) { if (data.Code == "200") { $currentImage1.remove(); $gallery1.fadeOut(100); } else { alertMessage(data.Msg, null); } }, { imageUrl: imageUrl }); }); $(".weui-gallery__del1 i.weui-icon-download") .click(function () { var imageUrl = $currentImage1.css("backgroundImage").replace('url("', '').replace('")', ""); window.open(imageUrl); }); function addMoment() { var temp = ""; $("#ulFiles") .find("li") .each(function() { temp += ';'+ $(this).attr("data-id"); }); $("#Image").val(temp.substr(1)); if (isNullEmptyUndefined($('#ppid').val()) || isNullEmptyUndefined($('#Image').val())) { alertMessage("请先输入ppid和上传图片"); return; } if (isNullEmptyUndefined($("#ftype").val())) { alertMessage("请联系IT开通权限"); return; } // $("#txtMsg").val("ppid:"+$('#ppid').val()+",Image:"+$('#Image').val()+",fType:"+$("#ftype").val()+",svrCode:"+dataForWeixin.SvrCode); ajaxobj.initajax("/Apibasis/MomentsAdd", "MomentsAdd", funAdd, { ppid: $('#ppid').val(), Image: $('#Image').val(), fType: $("#ftype").val(), svrCode: dataForWeixin.SvrCode }); } function funAdd(data) { if (data.Code == "200") { // window.location = "/Moments"; alertMessage(data.Msg, null); $('.weui-uploader__input-box').show(); $('#spanFileCount').text("0"); $('#ulFiles').html(""); uploadCount = 0; getImage(); } else { alertMessage(data.Msg, null); } } function getImage() { var ppid = $("#ppid").val(); var ftype = $("#ftype").val(); var CJUrl = $("#CJUrl").val(); if (isNullEmptyUndefined(ftype)) { alertMessage("请选择业务,如没有联系IT开通权限"); return; } ajaxobj.initajax("/Apibasis/HandUp", "getImage", function (data) { if (data.Code == "200") { var Data = data.Data; var html = ""; $.each(Data, function (i, v) { html += '<li class="weui-uploader__file" onclick=previewImage1(this) style="border-color: #999999;border-style: solid; border-width: 1px;background-image:url(\'' + CJUrl + v.Image_URL + '\')"></li>' }); $("#ulFiles1").html(html); } else { alertMessage(data.Msg, null); } }, { ppid: ppid, fType: ftype }); }
4.问题(这里碰到几个问题)
1)浏览器模拟微信浏览器(我这里使用的是谷歌)
这里可以F12进去=》More tools =》 Network conditions =》找到User agent,自行填写(可以参考上面页面视图代码获取User agent)
2)调试结果查看
这里可以使用官网的那个微信开发者工具(可以很明晰的看到返回Msg)
3)页面无法调用微信的扫一扫、上传图片功能
这个需要去配置,允许你这个服务器的站点JS
在配置中需要你下载一个微信的txt文件放到你服务器的指定目录下。(这里ASP.NET Core是需要放到wwwroot里头)
感谢:同事代码,嘿嘿嘿
https://blog.csdn.net/m0_68956554/article/details/140018049
https://blog.csdn.net/qq_44260798/article/details/115016638