微信JS-SDK开发过程中,使用getLocation获取坐标位置,如何将微信获取的坐标直接应用到百度地图中,显示以下效果:

说明:红色图标是从微信转换过来的位置,蓝色图标是周边位置。首先从微信开发流程讲解。

1、微信JS-SDK开发文档

首先进入官网的帮助文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN

可对文档进行详细的研读,要获取位置信息,分以下步骤:

第一步:绑定域名

进入微信公众号,找到“公众号设置”菜单,进入“功能设置”面板,

点击“设置”可设置引用js的相关域名:

第二步:引用官方js类库

在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js

引用页面是location.aspx,如下:

  1. <%@ Page Title="获取位置" Language="C#" AutoEventWireup="true" MasterPageFile="~/wxcrm/Site.Master" CodeFile="location.aspx.cs" Inherits="DTcms.Web.wxcrm.location" %>
  2.  
  3. <asp:Content ID="Content1" ContentPlaceHolderID="cphHead" runat="server">
  4. <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
  5. <script type="text/javascript">
  6. $("#mask").show();
  7. wx.config({
  8. debug: false, //开启调试模式,如为true,则弹出每个js函数调用情况
  9. appId: '<%= ResultJsData.GetValue("appid") %>', //必填,公众号的唯一标识
  10. timestamp: <%= ResultJsData.GetValue("timestamp") %>, //必填,生成签名的时间戳
  11. nonceStr: '<%= ResultJsData.GetValue("noncestr") %>', //必填,生成签名的随机串
  12. signature: '<%= ResultJsData.GetValue("signature") %>', //必填,签名
  13. jsApiList: [
  14. 'checkJsApi',
  15. 'onMenuShareTimeline',
  16. 'onMenuShareAppMessage',
  17. 'onMenuShareQQ',
  18. 'onMenuShareWeibo',
  19. 'hideMenuItems',
  20. 'showMenuItems',
  21. 'hideAllNonBaseMenuItem',
  22. 'showAllNonBaseMenuItem',
  23. 'translateVoice',
  24. 'startRecord',
  25. 'stopRecord',
  26. 'onRecordEnd',
  27. 'playVoice',
  28. 'pauseVoice',
  29. 'stopVoice',
  30. 'uploadVoice',
  31. 'downloadVoice',
  32. 'chooseImage',
  33. 'previewImage',
  34. 'uploadImage',
  35. 'downloadImage',
  36. 'getNetworkType',
  37. 'openLocation',
  38. 'getLocation',
  39. 'hideOptionMenu',
  40. 'showOptionMenu',
  41. 'closeWindow',
  42. 'scanQRCode',
  43. 'chooseWXPay',
  44. 'openProductSpecificView',
  45. 'addCard',
  46. 'chooseCard',
  47. 'openCard'
  48. ]
  49. });
  50. wx.ready(function(){
  51. wx.checkJsApi({
  52. jsApiList: [
  53. 'getNetworkType',
  54. 'previewImage',
  55. 'getLocation'
  56. ],
  57. success: function (res) {
  58. }
  59. });
  60. wx.getLocation({
  61. type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
  62. success: function (res) {
  63. try {
  64. var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
  65. var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
  66. var speed = res.speed; // 速度,以米/每秒计
  67. var accuracy = res.accuracy; // 位置精度
  68. //alert(JsonUti.convertToString(res));
  69. //wx.openLocation({
  70. // latitude: res.latitude, // 纬度,浮点数,范围为90 ~ -90
  71. // longitude: res.longitude, // 经度,浮点数,范围为180 ~ -180。
  72. // name: '当前位置', // 位置名
  73. // address: '点击查看', // 地址详情说明
  74. // scale: 28, // 地图缩放级别,整形值,范围从1~28。默认为最大
  75. // infoUrl: "location1.aspx?m=Home&c=Index&a=getlocation&latitude="+latitude+"&longitude="+longitude // 在查看位置界面底部显示的超链接,可点击跳转
  76. //});
  77. //alert(latitude+"-"+longitude);
  78. $("#mask").hide();
  79. window.location.href = "location1.aspx?m=Home&c=Index&a=getlocation&latitude=" +
  80. latitude +
  81. "&longitude=" +
  82. longitude +
  83. "&=speed" +
  84. speed +
  85. "&accuracy=" +
  86. accuracy;
  87. } catch (e) {
  88. alert(e.message);
  89. }
  90. },
  91. cancel: function (res) {
  92. window.location.href="none.aspx?msg=拒绝获取地理位置&r=" + Math.random();//拒绝
  93. },
  94. fail:function() {
  95. alert("未能获取地理位置!首先检查手机是否启用微信定位。");
  96. }
  97. });
  98. });
  99.  
  100. wx.error(function(res) {
  101. // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
  102. });
  103.  
  104. wx.fail(function(res) {
  105. });
  106. </script>
  107. </asp:Content>
  108. <asp:Content ID="Content2" ContentPlaceHolderID="cphTitle" runat="server">
  109. 获取位置
  110. </asp:Content>
  111. <asp:Content ID="Content3" ContentPlaceHolderID="cphContainer" runat="server">
  112. <br />
  113. <br />
  114. <center style="display: block;">
  115.  
  116. <i class="weui_icon_msg weui_icon_info"></i>
  117.  
  118. <div class="input_errow" style="width: 60%; height: 60%; text-align: center;">
  119. 正在获取地理位置信息...
  120. </div>
  121. </center>
  122.  
  123. <div class="mask" style="display: none;">
  124. <span>
  125. <img src="/templates/txwap/images/mask.gif" />
  126. </span>
  127. </div>
  128. </asp:Content>

页面效果:

注意事项:

(1)如果手机设置不允许微信获取位置信息,则提示以上信息。

(2)上图参数获取的是GPS坐标,如使用百度地图,要做一定转换,将在location1.aspx中体现。

(3)所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用。

对应location.aspx.cs实现:

  1. using Payment.WxWebHlper;
  2. using Payment.WxWebHlper.Actions;
  3. using System;
  4. using System.Globalization;
  5. using WxJsSDK;
  6. using WxPayAPI;
  7.  
  8. namespace DTcms.Web.wxcrm
  9. {
  10. public partial class location : PageBase
  11. {
  12. protected string appId { get; set; }
  13. protected string timestamp { get; set; }
  14. protected string nonceStr { get; set; }
  15. protected string signature { get; set; }
  16. public static string WxJsApiParam { get; set; }
  17. public WxJsData ResultJsData { get; set; }
  18.  
  19. protected void Page_Load(object sender, EventArgs e)
  20. {
  21. JudgeCode();
  22. var webAuthorize = new WebAuthorizeAction();
  23. Code2TokenResult = webAuthorize.Code2Token(Request["code"]);
  24. if (Code2TokenResult.HasError())
  25. {
  26. Response.Redirect(Urls.PageOfLocation);
  27. GotoNonePage("获取用户凭证失败,请重新获取");
  28. return;
  29. }
  30. GetUserInfoResult = webAuthorize.GetUserInfo(Code2TokenResult.access_token);
  31. if (GetUserInfoResult.HasError())
  32. {
  33. GotoNonePage("获取用户信息失败,请重新获取");
  34. }
  35. var userid = wxOperation.HasBind(GetUserInfoResult.openid);
  36. if (userid.Equals(Guid.Empty))
  37. {
  38. Response.Redirect(Urls.Oauth2Url);
  39. GotoNonePage("微信用户未绑定");
  40. }
  41.  
  42. appId = WxPayConfig.APPID;
  43. timestamp = WxPayApi.GenerateTimeStamp();
  44. nonceStr = WxPayApi.GenerateNonceStr();
  45. //以下实现将在3、核心代码实现 体现
  1. var jsApi = new JsApi(this);
  2. ResultJsData = jsApi.GetJsData();
  3. WxJsApiParam = jsApi.GetJsApiParameters();//获取H5调起JS API参数
  4. }
  5. }
  6. }

2、将微信GPS坐标转换为百度坐标

微信获取坐标成功后,页面自动跳转到location1.aspx,处理流程如下:

微信坐标—>转换为百度地图坐标—>根据百度地图API获取位置信息—>根据百度地图API显示坐标

  1. <%@ Page Title="在线签到" Language="C#" MasterPageFile="~/wxcrm/Site.Master" AutoEventWireup="true" CodeFile="location1.aspx.cs" Inherits="DTcms.Web.wxcrm.location1" %>
  2.  
  3. <asp:Content ID="Content1" ContentPlaceHolderID="cphHead" runat="server">
  4. <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
  5. <style type="text/css">
  6. #allmap { width: 100%; height: 300px; }
  7. </style>
  8. <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=dhRLKMR9QUO4wHmnnSZTarta"></script>
  9. <script type="text/javascript">
  10. //GPS坐标
  11. var yy = <%= this.Request["longitude"] %>; //经度,浮点数,范围为180 ~ -180。
  12. var xx = <%= this.Request["latitude"] %>; //纬度,浮点数,范围为90 ~ -90
  13. var gpsPoint = new BMap.Point(xx,yy);
  14. var bxx = 0.0;
  15. var byy = 0.0;
  16.  
  17. /*
  18. * http://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition
  19. */
  20. var PositionUrl = "http://api.map.baidu.com/geoconv/v1/?";
  21. function changePosition(){
  22. var str = "coords="+yy+","+xx+"&from=1&to=5";
  23. var url = PositionUrl + str;
  24. $("#positionUrl").html(url+"&ak=dhRLKMR9QUO4wHmnnSZTartg");
  25. var script = document.createElement('script');
  26. script.src = url + '&ak=dhRLKMR9QUO4wHmnnSZTarta&callback=dealResult';
  27. document.getElementsByTagName("head")[0].appendChild(script);
  28. }
  29. function dealResult(msg){
  30. if(msg.status != 0){
  31. alert("无正确的返回结果。");
  32. $("#mask").hide();
  33. return;
  34. }
  35. //JsonUti.convertToString(msg);
  36. bxx = msg.result[0].x;
  37. byy = msg.result[0].y;
  38. doOptions();
  39. }
  40.  
  41. function getBaiduPosition() {
  42. var url ="http://api.map.baidu.com/geoconv/v1/?coords="+yy+","+xx+"&from=1&to=5&ak=dhRLKMR9QUO4wHmnnSZTarta";
  43. $.ajax({
  44. url: url,
  45. success: function(data,status,xhr) {
  46. alert(status);
  47. alert(data.status);
  48. },
  49. dataType: json
  50. });
  51. }
  52.  
  53. var ADVANCED_POST = '';
  54. var advancedOptions = '';
  55. var address;
  56. var map;
  57.  
  58. function renderOption(response) {
  59. var html = '';
  60. if (response.status ) {
  61. $("#mask").hide();
  62. var text = "无正确的返回结果!";
  63. alert(text);
  64. return;
  65. }
  66. var result = response.result;
  67. var location = response.result.location;
  68. var uri = 'http://api.map.baidu.com/marker?location='+ location.lat+','+location.lng +'&title='+response.result.level+'&content='+address+'&output=html';
  69. var staticimageUrl = "http://api.map.baidu.com/staticimage?center=" + location.lng+','+location.lat + "&markers=" + location.lng+','+location.lat;
  70. html = '<p>坐标:纬度: ' + location.lat + " 经度: " + location.lng+'<br />';
  71. html += '精度: '+response.result.precise+'<br />' ;
  72. html += '可信度: '+response.result.confidence +'<br />';
  73. html += '地址类型: '+response.result.level+'</p>' ;
  74. html += '<p><img src="' + staticimageUrl + '" /></p>' ;
  75. html += '<p>分享该点: <a href="' + uri + '" target="_blank">' + uri + '</a></p>'; //将该链接设置成可单击
  76. // 百度地图API功能
  77. map = new BMap.Map("allmap");
  78. var point = new BMap.Point(bxx, byy);
  79. var marker = new BMap.Marker(point); // 创建标注
  80. map.addOverlay(marker); // 将标注添加到地图中
  81. map.centerAndZoom(point, 100);
  82. var opts = {
  83. width: 200, // 信息窗口宽度
  84. height: 100, // 信息窗口高度
  85. title: "我的位置", // 信息窗口标题
  86. enableMessage: true,//设置允许信息窗发送短息
  87. message: result.formatted_address
  88. }
  89.  
  90. $("#divPo").html("当前位置:" + result.formatted_address);
  91. var infoWindow = new BMap.InfoWindow(result.formatted_address, opts); // 创建信息窗口对象
  92. marker.addEventListener("click", function () {
  93. map.openInfoWindow(infoWindow, point); //开启信息窗口
  94. });
  95.  
  96. var myIcon = new BMap.Icon("http://api.map.baidu.com/img/markers.png", new BMap.Size(23, 25), {
  97. offset: new BMap.Size(10, 25), // 指定定位位置
  98. imageOffset: new BMap.Size(0, 0 - 10 * 25) // 设置图片偏移
  99. });
  100.  
  101. var pois = result.pois;
  102. for(var i=0;i<pois.length;i++){
  103. var marker = new BMap.Marker(new BMap.Point(pois[i].point.x,pois[i].point.y),{icon:myIcon}); // 创建标注
  104. var name = pois[i].name;
  105. var addr = pois[i].addr;
  106. map.addOverlay(marker); // 将标注添加到地图中
  107. addClickHandler(name,addr,marker);
  108. }
  109.  
  110. $("#mask").hide();
  111. $("#btnSign").show();
  112. return;
  113. }
  114.  
  115. function addClickHandler(name,addr,marker){
  116. marker.addEventListener("click",function(e){
  117. openInfo(name,addr,e)}
  118. );
  119. }
  120.  
  121. function openInfo(name,addr,e){
  122. var p = e.target;
  123. var point = new BMap.Point(p.getPosition().lng, p.getPosition().lat);
  124. var opts = {
  125. width: 200, // 信息窗口宽度
  126. height: 100, // 信息窗口高度
  127. title: name, // 信息窗口标题
  128. enableMessage: true,//设置允许信息窗发送短息
  129. message: addr
  130. }
  131. var infoWindow = new BMap.InfoWindow(addr,opts); // 创建信息窗口对象
  132. map.openInfoWindow(infoWindow,point); //开启信息窗口
  133. }
  134.  
  135. function doOptions() {
  136. var script = document.createElement('script');
  137. script.type = 'text/javascript';
  138. ADVANCED_POST ="http://api.map.baidu.com/geocoder/v2/?ak=dhRLKMR9QUO4wHmnnSZTartg&callback=renderOption&location=" + byy + ","+bxx+ "&output=json&pois=2";
  139. script.src = ADVANCED_POST;
  140. document.body.appendChild(script);
  141. };
  142.  
  143. $(function () {
  144. $("#mask").show();
  145. $("#btnSign").hide();
  146. changePosition();
  147. });
  148. </script>
  149. </asp:Content>
  150. <asp:Content ID="Content2" ContentPlaceHolderID="cphTitle" runat="server">
  151. 在线签到
  152. </asp:Content>
  153. <asp:Content ID="Content3" ContentPlaceHolderID="cphContainer" runat="server">
  154. <form id="frmLocation" runat="server">
  155. <div class="box mb50">
  156. <div class="hd"><span>位置信息</span></div>
  157. <div class="bd" style="padding-left: 0">
  158. <ul class="stipx" style="height: 300px;">
  159. <div id="allmap"></div>
  160. </ul>
  161. </div>
  162. <div class="bd" style="padding-left: 0">
  163. <ul class="stipx">
  164. <div id="divPo"></div>
  165. </ul>
  166. </div>
  167. </div>
  168. <div class="next_btn" style="text-align: center; margin-top: -50px;">
  169. <input id="btnSign" type="button" value="我要签到" style="cursor: pointer; width: 210px; height: 50px; border-radius: 15px; background-color: #00CD00; border: 0px #FE6714 solid; cursor: pointer; color: white; font-size: 16px;" />
  170. </div>
  171. <div class="mask" style="display: none;">
  172. <span>
  173. <img src="/templates/txwap/images/mask.gif" />
  174. </span>
  175. </div>
  176. </form>
  177. </asp:Content>

本页面主要涉及到百度地图开放平台,要申请百度地图ag。否则调用js则提示:APP不存在,AK有误请重新检查在重试。

(1)百度地图技术一:坐标转换API

官网地址:http://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition

API服务地址:http://api.map.baidu.com/geoconv/v1/?

文档有详细的说明,不再赘述哦。

(2)百度地图技术二:根据坐标获取位置

官网网址:http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding

Geocoding API包括地址解析和逆地址解析功能:

地理编码:即地址解析,由详细到街道的结构化地址得到百度经纬度信息,例如:“北京市海淀区中关村南大街27号”地址解析的结果是“lng:116.31985,lat:39.959836”。同时,地理编码也支持名胜古迹、标志性建筑名称直接解析返回百度经纬度,例如:“百度大厦”地址解析的结果是“lng:116.30815,lat:40.056885” ,通用的POI检索需求,建议使用Place API。

逆地理编码:即逆地址解析,由百度经纬度信息得到结构化地址信息,例如:“lat:31.325152,lng:120.558957”逆地址解析的结果是“江苏省苏州市虎丘区塔园路318号”。

API服务地址:http://api.map.baidu.com/geocoder/v2/

具体参数可查看官方文档。

示例:http://api.map.baidu.com/geocoder/v2/?ak=申请的百度KEY&location=34.79563,114.23075222912&callback=showLocation&output=xml&pois=1

注意事项:

(1)百度开发者key申请

(2)百度地图坐标系统与微信的坐标系统不同

(3)api调用地址及参数说明

(4)api回调函数意义

(5)理解json与jsonp的含义,详情查看:http://kb.cnblogs.com/page/139725/

3、微信JS-SDK核心代码

(1)JsAPI.cs生成相关JS-SDK配置参数

  1. using System;
  2. using System.Globalization;
  3. using System.Linq;
  4. using System.Web.Security;
  5. using System.Web.UI;
  6. using WxPayAPI;
  7.  
  8. namespace WxJsSDK
  9. {
  10. public class JsApi
  11. {
  12. /// <summary>
  13. /// 保存页面对象,因为要在类的方法中使用Page的Request对象
  14. /// </summary>
  15. private Page page { get; set; }
  16.  
  17. public WxJsData ResultJsData { get; set; }
  18.  
  19. /// <summary>
  20. ///
  21. /// </summary>
  22. /// <param name="page"></param>
  23. public JsApi(Page page)
  24. {
  25. this.page = page;
  26. }
  27.  
  28. public WxJsData GetJsData()
  29. {
  30. var data = new WxJsData();
  31. data.SetValue("appid", WxPayConfig.APPID);//公众账号ID
  32. data.SetValue("timestamp", WxPayApi.GenerateTimeStamp());
  33. data.SetValue("noncestr", WxPayApi.GenerateNonceStr());//随机字符串
  34.  
  35. var url = GetUrl();
  36. data.SetValue("url", url);
  37. var jsToken = GetJsApiTicket();
  38. data.SetValue("jsapi_ticket", jsToken);
  39. var signature = MakeSignature(jsToken, data.GetValue("noncestr").ToString(), data.GetValue("timestamp").ToString(), url);
  40. data.SetValue("signature", signature);
  41.  
  42. ResultJsData = data;
  43. return data;
  44. }
  45.  
  46. private string MakeSignature(string jsapiTicket, string noncestr, string timestamp, string url)
  47. {
  48. string[] arrayList =
  49. {
  50. "jsapi_ticket=" + jsapiTicket,
  51. "timestamp=" + timestamp,
  52. "noncestr=" + noncestr,
  53. "url=" + url
  54. };
  55. Array.Sort(arrayList);
  56. var signature = string.Join("&", arrayList);
  57. signature = FormsAuthentication.HashPasswordForStoringInConfigFile(signature, "SHA1").ToLower();
  58. return signature;
  59. }
  60.  
  61. private string GetJsApiTicket()
  62. {
  63. var jsAuth = new JsAuthorizeAction();
  64. var token = jsAuth.GetToken();
  65. var nd = DateTime.Now - token.CreateDate;
  66. Log.Error(this.GetType().ToString(), token.access_token);
  67. Log.Error(this.GetType().ToString(), token.IsValid().ToString());
  68. if (token.IsValid())
  69. return jsAuth.GetJsApiTicket(token.access_token).ticket;
  70. return "";
  71. }
  72.  
  73. private string GetUrl()
  74. {
  75. string host = page.Request.Url.Host;
  76. string path = page.Request.Path;
  77. string queryString = page.Request.Url.Query;
  78. //这个地方要注意,参与签名的是网页授权获取用户信息时微信后台回传的完整url
  79. string url = "http://" + host + path + queryString;
  80. return url;
  81. }
  82.  
  83. public string GetJsApiParameters()
  84. {
  85. Log.Debug(this.GetType().ToString(), "JsApi ::GetJsApiParam is processing...");
  86.  
  87. string parameters = ResultJsData.ToJson();
  88.  
  89. Log.Debug(this.GetType().ToString(), "Get JsApi : " + parameters);
  90. return parameters;
  91. }
  92. }
  93. }

(2)JsAuthorizeAction.cs微信JS-SDK相关API调用函数

  1. using Payment.WxWebHlper;
  2. using Payment.WxWebHlper.Results;
  3. using System;
  4. using WxPayAPI;
  5.  
  6. namespace WxJsSDK
  7. {
  8. public class JsAuthorizeAction
  9. {
  10. private static TokenResult Token = new TokenResult() { errcode = -1 };
  11. private static JsApiTicketResult JsApiTicket = new JsApiTicketResult() { errcode = -1 };
  12.  
  13. public TokenResult GetToken()
  14. {
  15. Log.Error(this.GetType().ToString(), "GetToken");
  16. if (!Token.IsValid())
  17. {
  18. Token = GeTokenResult();
  19. Log.Error(this.GetType().ToString(), Token.ToString());
  20. }
  21. return Token;
  22. }
  23.  
  24. /// <summary>
  25. ///
  26. /// </summary>
  27. /// <returns></returns>
  28. public TokenResult GeTokenResult()
  29. {
  30. var result = new TokenResult();
  31. try
  32. {
  33. var webUtils = new WebUtils();
  34. var url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", WxPayConfig.APPID, WxPayConfig.APPSECRET);
  35. var strRtn = webUtils.Get(url);
  36. result = Tools.JsonStringToObj<TokenResult>(strRtn);
  37. }
  38. catch (Exception ex)
  39. {
  40. Log.Error(this.GetType().ToString(), ex.Message);
  41. result = new TokenResult() { errcode = -1086 };
  42. }
  43. return result;
  44. }
  45.  
  46. /// <summary>
  47. ///
  48. /// </summary>
  49. /// <param name="token"></param>
  50. /// <returns></returns>
  51. public JsApiTicketResult GetJsApiTicket(string token)
  52. {
  53. Log.Error(this.GetType().ToString(), "GetJsApiTicket传入token:" + token);
  54. if (!JsApiTicket.IsValid())
  55. {
  56. JsApiTicket = GetJsApiTicketResult(token);
  57. }
  58. return JsApiTicket;
  59. }
  60.  
  61. /// <summary>
  62. ///
  63. /// </summary>
  64. /// <param name="token"></param>
  65. /// <returns></returns>
  66. public JsApiTicketResult GetJsApiTicketResult(string token)
  67. {
  68. JsApiTicketResult result;
  69. try
  70. {
  71. var webUtils = new WebUtils();
  72. var url = string.Format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi", token);
  73. var strRtn = webUtils.Get(url);
  74. result = Tools.JsonStringToObj<JsApiTicketResult>(strRtn);
  75. }
  76. catch (Exception ex)
  77. {
  78. Log.Error(this.GetType().ToString(), ex.Message);
  79. result = new JsApiTicketResult() { errcode = -1086 };
  80. }
  81. return result;
  82. }
  83. }
  84.  
  85. public class JsApiTicketResult : ReturnResult
  86. {
  87. /// <summary>
  88. /// 构造函数
  89. /// </summary>
  90. public JsApiTicketResult()
  91. {
  92. CreateDate = DateTime.Now;
  93. }
  94.  
  95. /// <summary>
  96. ///
  97. /// </summary>
  98. public string ticket { get; set; }
  99.  
  100. /// <summary>
  101. /// access_token接口调用凭证超时时间,单位(秒)
  102. /// </summary>
  103. public int expires_in { get; set; }
  104.  
  105. /// <summary>
  106. /// 创建时间
  107. /// </summary>
  108. public DateTime CreateDate { get; set; }
  109.  
  110. /// <summary>
  111. /// 判断是否有效
  112. /// </summary>
  113. /// <returns></returns>
  114. public bool IsValid()
  115. {
  116. if (this.errcode != 0)
  117. return false;
  118. var nd = DateTime.Now - CreateDate;
  119. return nd.Seconds < 7200;
  120. }
  121. }
  122.  
  123. public class TokenResult : ReturnResult
  124. {
  125. /// <summary>
  126. /// 构造函数
  127. /// </summary>
  128. public TokenResult()
  129. {
  130. CreateDate = DateTime.Now;
  131. }
  132.  
  133. /// <summary>
  134. /// 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
  135. /// </summary>
  136. public string access_token { get; set; }
  137.  
  138. /// <summary>
  139. /// access_token接口调用凭证超时时间,单位(秒)
  140. /// </summary>
  141. public int expires_in { get; set; }
  142.  
  143. /// <summary>
  144. /// 创建时间
  145. /// </summary>
  146. public DateTime CreateDate { get; set; }
  147.  
  148. /// <summary>
  149. /// 判断是否有效
  150. /// </summary>
  151. /// <returns></returns>
  152. public bool IsValid()
  153. {
  154. if (this.errcode != 0)
  155. return false;
  156. var nd = DateTime.Now - CreateDate;
  157. return nd.Seconds < 7200;
  158. }
  159. }
  160. }

(3)WxJsData.cs微信JS-SDK参数类

  1. using LitJson;
  2. using System.Collections.Generic;
  3. using System.Security.Cryptography;
  4. using System.Text;
  5. using System.Xml;
  6. using WxPayAPI;
  7.  
  8. namespace WxJsSDK
  9. {
  10. public class WxJsData
  11. {
  12. private SortedDictionary<string, object> m_values = new SortedDictionary<string, object>();
  13. /**
  14. * 设置某个字段的值
  15. * @param key 字段名
  16. * @param value 字段值
  17. */
  18.  
  19. public void SetValue(string key, object value)
  20. {
  21. m_values[key] = value;
  22. }
  23.  
  24. /**
  25. * 根据字段名获取某个字段的值
  26. * @param key 字段名
  27. * @return key对应的字段值
  28. */
  29.  
  30. public object GetValue(string key)
  31. {
  32. object o = null;
  33. m_values.TryGetValue(key, out o);
  34. return o;
  35. }
  36.  
  37. /**
  38. * 判断某个字段是否已设置
  39. * @param key 字段名
  40. * @return 若字段key已被设置,则返回true,否则返回false
  41. */
  42.  
  43. public bool IsSet(string key)
  44. {
  45. object o = null;
  46. m_values.TryGetValue(key, out o);
  47. if (null != o)
  48. return true;
  49. return false;
  50. }
  51.  
  52. /**
  53. * @将Dictionary转成xml
  54. * @return 经转换得到的xml串
  55. * @throws WxPayException
  56. **/
  57.  
  58. public string ToXml()
  59. {
  60. //数据为空时不能转化为xml格式
  61. if (0 == m_values.Count)
  62. {
  63. Log.Error(this.GetType().ToString(), "WxPayData数据为空!");
  64. throw new WxPayException("WxPayData数据为空!");
  65. }
  66.  
  67. string xml = "<xml>";
  68. foreach (KeyValuePair<string, object> pair in m_values)
  69. {
  70. //字段值不能为null,会影响后续流程
  71. if (pair.Value == null)
  72. {
  73. Log.Error(this.GetType().ToString(), "WxPayData内部含有值为null的字段!");
  74. throw new WxPayException("WxPayData内部含有值为null的字段!");
  75. }
  76.  
  77. if (pair.Value.GetType() == typeof(int) || pair.Value.GetType() == typeof(decimal))
  78. {
  79. xml += "<" + pair.Key + ">" + pair.Value.ToString() + "</" + pair.Key + ">";
  80. }
  81. else if (pair.Value.GetType() == typeof(string))
  82. {
  83. xml += "<" + pair.Key + ">" + "<![CDATA[" + pair.Value + "]]></" + pair.Key + ">";
  84. }
  85. else//除了string和int类型不能含有其他数据类型
  86. {
  87. Log.Error(this.GetType().ToString(), "WxPayData字段数据类型错误!");
  88. throw new WxPayException("WxPayData字段数据类型错误!");
  89. }
  90. }
  91. xml += "</xml>";
  92. return xml;
  93. }
  94.  
  95. /**
  96. * @将xml转为WxPayData对象并返回对象内部的数据
  97. * @param string 待转换的xml串
  98. * @return 经转换得到的Dictionary
  99. * @throws WxPayException
  100. */
  101.  
  102. public SortedDictionary<string, object> FromXml(string xml)
  103. {
  104. if (string.IsNullOrEmpty(xml))
  105. {
  106. Log.Error(this.GetType().ToString(), "将空的xml串转换为WxPayData不合法!");
  107. throw new WxPayException("将空的xml串转换为WxPayData不合法!");
  108. }
  109.  
  110. XmlDocument xmlDoc = new XmlDocument();
  111. xmlDoc.LoadXml(xml);
  112. XmlNode xmlNode = xmlDoc.FirstChild;//获取到根节点<xml>
  113. XmlNodeList nodes = xmlNode.ChildNodes;
  114. foreach (XmlNode xn in nodes)
  115. {
  116. XmlElement xe = (XmlElement)xn;
  117. m_values[xe.Name] = xe.InnerText;//获取xml的键值对到WxPayData内部的数据中
  118. }
  119.  
  120. try
  121. {
  122. //2015-06-29 错误是没有签名
  123. if (m_values["return_code"] != "SUCCESS")
  124. {
  125. return m_values;
  126. }
  127. CheckSign();//验证签名,不通过会抛异常
  128. }
  129. catch (WxPayException ex)
  130. {
  131. throw new WxPayException(ex.Message);
  132. }
  133.  
  134. return m_values;
  135. }
  136.  
  137. /**
  138. * @Dictionary格式转化成url参数格式
  139. * @ return url格式串, 该串不包含sign字段值
  140. */
  141.  
  142. public string ToUrl()
  143. {
  144. string buff = "";
  145. foreach (KeyValuePair<string, object> pair in m_values)
  146. {
  147. if (pair.Value == null)
  148. {
  149. Log.Error(this.GetType().ToString(), "WxPayData内部含有值为null的字段!");
  150. throw new WxPayException("WxPayData内部含有值为null的字段!");
  151. }
  152.  
  153. if (pair.Key != "sign" && pair.Value.ToString() != "")
  154. {
  155. buff += pair.Key + "=" + pair.Value + "&";
  156. }
  157. }
  158. buff = buff.Trim('&');
  159. return buff;
  160. }
  161.  
  162. /**
  163. * @Dictionary格式化成Json
  164. * @return json串数据
  165. */
  166.  
  167. public string ToJson()
  168. {
  169. string jsonStr = JsonMapper.ToJson(m_values);
  170. return jsonStr;
  171. }
  172.  
  173. /**
  174. * @values格式化成能在Web页面上显示的结果(因为web页面上不能直接输出xml格式的字符串)
  175. */
  176.  
  177. public string ToPrintStr()
  178. {
  179. string str = "";
  180. foreach (KeyValuePair<string, object> pair in m_values)
  181. {
  182. if (pair.Value == null)
  183. {
  184. Log.Error(this.GetType().ToString(), "WxPayData内部含有值为null的字段!");
  185. throw new WxPayException("WxPayData内部含有值为null的字段!");
  186. }
  187.  
  188. str += string.Format("{0}={1}<br>", pair.Key, pair.Value.ToString());
  189. }
  190. Log.Debug(this.GetType().ToString(), "Print in Web Page : " + str);
  191. return str;
  192. }
  193.  
  194. /**
  195. * @生成签名,详见签名生成算法
  196. * @return 签名, sign字段不参加签名
  197. */
  198.  
  199. public string MakeSign()
  200. {
  201. //转url格式
  202. string str = ToUrl();
  203. //在string后加入API KEY
  204. str += "&key=" + WxPayConfig.KEY;
  205. //MD5加密
  206. var md5 = MD5.Create();
  207. var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
  208. var sb = new StringBuilder();
  209. foreach (byte b in bs)
  210. {
  211. sb.Append(b.ToString("x2"));
  212. }
  213. //所有字符转为大写
  214. string result = sb.ToString().ToUpper();
  215. return result;
  216. }
  217.  
  218. public string MakeAppSign()
  219. {
  220. //转url格式
  221. string str = ToUrl();
  222. //在string后加入API KEY
  223. str += "&key=" + WxPayConfig.KEYofAPP;
  224. //MD5加密
  225. var md5 = MD5.Create();
  226. var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
  227. var sb = new StringBuilder();
  228. foreach (byte b in bs)
  229. {
  230. sb.Append(b.ToString("x2"));
  231. }
  232. //所有字符转为大写
  233. string result = sb.ToString().ToUpper();
  234. return result;
  235. }
  236.  
  237. /**
  238. *
  239. * 检测签名是否正确
  240. * 正确返回true,错误抛异常
  241. */
  242.  
  243. public bool CheckSign()
  244. {
  245. //如果没有设置签名,则跳过检测
  246. if (!IsSet("sign"))
  247. {
  248. Log.Error(this.GetType().ToString(), "WxPayData签名存在但不合法!");
  249. throw new WxPayException("WxPayData签名存在但不合法!");
  250. }
  251. //如果设置了签名但是签名为空,则抛异常
  252. if (GetValue("sign") == null || GetValue("sign").ToString() == "")
  253. {
  254. Log.Error(this.GetType().ToString(), "WxPayData签名存在但不合法!");
  255. throw new WxPayException("WxPayData签名存在但不合法!");
  256. }
  257.  
  258. //获取接收到的签名
  259. string return_sign = GetValue("sign").ToString();
  260.  
  261. //在本地计算新的签名
  262. string cal_sign = MakeSign();
  263.  
  264. if (cal_sign == return_sign)
  265. {
  266. return true;
  267. }
  268.  
  269. Log.Error(this.GetType().ToString(), "WxPayData签名验证错误!");
  270. throw new WxPayException("WxPayData签名验证错误!");
  271. }
  272.  
  273. /**
  274. * @获取Dictionary
  275. */
  276.  
  277. public SortedDictionary<string, object> GetValues()
  278. {
  279. return m_values;
  280. }
  281. }
  282. }

提示信息:相关解析思路可参考微信公众号支付官方SDK,下载地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=11_1

提示:承接微信应用开发,有意者QQ联系2339698190

微信JS-SDK坐标位置转换为百度地图坐标的更多相关文章

  1. GPS坐标转换为百度地图坐标

    /** * GPS坐标转换为百度地图坐标 * 需要引入javabase64.jar 和json的一些包 * */ public class Gps2BaiDu { public static void ...

  2. 微信小程序城市定位(借助百度地图API判断城市)

    概述 微信小程序提供一些API(地址)用于获取当前用户的地理位置等信息,但无论是wx.getLocation,还是wx.chooseLocation均没有单独的字段表示国家与城市信息,仅有经纬度信息. ...

  3. GPS坐标显示在百度地图上(Qt+百度地图)

    Qt在5.6以后的版本就不支持webview控件了,这里我用的是Qt5.4的版本,里面还有这个控件: 下面简单介绍下Qt与html中的javascript调用交互过程: 一.整体实现介绍 在html中 ...

  4. GPS坐标转百度地图坐标

    百度地图提供了相关API:BMap.Convertor.translate, 但是使用上存在部分限制:1.次数限制:2.异步回调 可以用如下方法: /** * 地图位置计算工具(将GPS坐标转换成百度 ...

  5. GPS定位为什么要转换处理?高德地图和百度地图坐标处理有什么不一样?

    GPS定位为什么要转换处理?高德地图和百度地图坐标处理有什么不一样? 先了解一下 高德地图 采用: GCJ-02 (不可逆) 百度百科: http://baike.baidu.com/link?url ...

  6. 实战微信JS SDK开发:贺卡制作与播放(1)

    前段时间忙于CanTK 2.0的开发,所以博客一直没有更新.CanTK 2.0主要增强了游戏和富媒体的开发,现在编码和测试基本完成了,等文档完成了再正式发布,里面有不少激动人心的功能,等发布时再一一细 ...

  7. 微信JS SDK接入的几点注意事项

    微信JS SDK接入,主要可以先参考官网说明文档,总结起来有几个步骤: 1.绑定域名:先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”.备注:登录后可在“开发者中心”查看对 ...

  8. 微信js sdk上传多张图片

    微信js sdk上传多张图片,微信上传多张图片 该案例已tp3.2商城为例 直接上代码: php代码: public function ind(){ $appid="111111111111 ...

  9. 微信小程序,天气预报(百度地图开放平台API)

    小程序看似一种全新的东西,但好在基本上就是曾经HTML,CSS,JS的一个微变版本. 语法和之前一样.只是一些用法和名字(标签)发生了一些变化. 小程序主要就四种扩展名的文件:js,json,wxml ...

随机推荐

  1. MySQL数据库和InnoDB存储引擎文件

    参数文件 当MySQL示例启动时,数据库会先去读一个配置参数文件,用来寻找数据库的各种文件所在位置以及指定某些初始化参数,这些参数通常定义了某种内存结构有多大等.在默认情况下,MySQL实例会按照一定 ...

  2. 使用技术手段限制DBA的危险操作—Oracle Database Vault

    概述 众所周知,在业务高峰期,某些针对Oracle数据库的操作具有很高的风险,比如修改表结构.修改实例参数等等,如果没有充分评估和了解这些操作所带来的影响,这些操作很可能会导致故障,轻则导致应用错误, ...

  3. Oracle数据库该如何着手优化一个SQL

    这是个终极问题,因为优化本身的复杂性实在是难以总结的,很多时候优化的方法并不是用到了什么高深莫测的技术,而只是一个思想意识层面的差异,而这些都很可能连带导致性能表现上的巨大差异. 所以有时候我们应该先 ...

  4. 代码的坏味道(17)——夸夸其谈未来性(Speculative Generality)

    坏味道--夸夸其谈未来性(Speculative Generality) 特征 存在未被使用的类.函数.字段或参数. 问题原因 有时,代码仅仅为了支持未来的特性而产生,然而却一直未实现.结果,代码变得 ...

  5. python10作业思路及源码:类Fabric主机管理程序开发(仅供参考)

    类Fabric主机管理程序开发 一,作业要求 1, 运行程序列出主机组或者主机列表(已完成) 2,选择指定主机或主机组(已完成) 3,选择主机或主机组传送文件(上传/下载)(已完成) 4,充分使用多线 ...

  6. jQuery可自动播放动画焦点图插件Koala

    Koala是一款简单而实用的jQuery焦点图幻灯片插件,焦点图不仅可以在播放图片的时候让图片有淡入淡出的动画效果,而且图片可以自动播放.该jQuery焦点图的每一张图片都可以设置文字描述,并浮动在图 ...

  7. PHP设计模式(五)建造者模式(Builder For PHP)

    建造者模式:将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示的设计模式. 设计场景: 有一个用户的UserInfo类,创建这个类,需要创建用户的姓名,年龄,爱好等信息,才能获得用 ...

  8. 体验报告:微信小程序在安卓机和苹果机上的区别

    很多人可能会问:微信小程序和在微信里面浏览一个网页有什么区别? 首先,小程序的运行是全屏的,界面跟进入了一个APP很像,更为沉浸跟在微信里面访问h5不一样:其次,它的浏览体验更为稳定. 不过,这还不够 ...

  9. webpack学习总结

    前言 在还未接触webpack,就有几个疑问: 1. webpack本质上是什么? 2. 跟异步模块加载有关系吗? 3. 可否生成多个文件,一定是一个? 4. 被引用的文件有其他异步加载模块怎么办? ...

  10. Android中Fragment的两种创建方式

    fragment是Activity中用户界面的一个行为或者是一部分.你可以在一个单独的Activity上把多个Fragment组合成为一个多区域的UI,并且可以在多个Activity中再使用.你可以认 ...