查看: 377|回复: 0

[ASP.NET教程] C#实现微信结合百度api获取当前用户地理位置的方法

发表于 2018-2-10 08:00:07

本文实例讲述了C#实现微信结合百度api获取当前用户地理位置的方法。分享给大家供大家参考,具体如下:

操作步骤:

1. 先根据微信提供的接口文档获取到经纬度

参考文档地址:http://mp.weixin./wiki/8/1b86529d05db9f960e48c3c7ca5be288.html

2. 由于直接使用微信获取到的经纬度,来使用百度地图api获取地址存在500~1000米的偏差,有时候定位不是很准确,所以需要转换成百度的坐标

参考文档地址:http://developer./map/index.php?title=webapi/guide/changeposition

3. 根据百度api实现逆地址解析,获取当前位置

参考文档地址:http://developer./map/index.php?title=webapi/guide/webservice-geocoding

具体实例:

该例子是mvc项目

1. WX_Location.cshtml页面:

  1. @using System.Web.Optimization;
  2. @{
  3. Layout = "~/Views/Shared/Master/_App.cshtml";
  4. }
  5. @section Head{
  6. }
  7. <div data-role="page">
  8. <div data-role="header" id="header" data-position="fixed">
  9. <h1>微信定位页面</h1>
  10. </div>
  11. <div data-role="content" class="ui-content">
  12. <form id="add" method="post" onsubmit="return false">
  13. <table border="0" cellpadding="0" cellspacing="0" class="register_table">
  14. <tr class='tr_bg neiy'>
  15. <td class='tdl neiy'>定位:</td>
  16. <td class='tdr'><input id='txt_dw' name='dw' type='text' placeholder='正在定位' class='td_input' value='' /></td></tr>
  17. </table>
  18. <div data-role="footer" data-position="fixed" data-id="footernav">
  19. <div data-role="navbar">
  20. <ul>
  21. <li><a href="" style=" rel="external nofollow" font-size: 1em;">返回主页</a></li>
  22. </ul>
  23. </div>
  24. </div>
  25. @Html.AntiForgeryToken()
  26. </form>
  27. </div>
  28. </div>
  29. @section scripts{
  30. @*微信js-sdk*@
  31. <script src="http://res.wx./open/js/jweixin-1.0.0.js" type="text/javascript"></script>
  32. <script type="text/javascript">
  33. //微信jssdk配置
  34. wx.config({
  35. debug: false,
  36. appId: "",
  37. timestamp: "@Html.Raw(ViewData["timestamp"])",
  38. nonceStr: "@Html.Raw(ViewData["nonceStr"])",
  39. signature: "@Html.Raw(ViewData["signature"])",
  40. jsApiList: [
  41. 'checkJsApi',
  42. 'onMenuShareTimeline',
  43. 'onMenuShareAppMessage',
  44. 'onMenuShareQQ',
  45. 'onMenuShareWeibo',
  46. 'hideMenuItems',
  47. 'showMenuItems',
  48. 'hideAllNonBaseMenuItem',
  49. 'showAllNonBaseMenuItem',
  50. 'translateVoice',
  51. 'startRecord',
  52. 'stopRecord',
  53. 'onRecordEnd',
  54. 'playVoice',
  55. 'pauseVoice',
  56. 'stopVoice',
  57. 'uploadVoice',
  58. 'downloadVoice',
  59. 'chooseImage',
  60. 'previewImage',
  61. 'uploadImage',
  62. 'downloadImage',
  63. 'getNetworkType',
  64. 'openLocation',
  65. 'getLocation',
  66. 'hideOptionMenu',
  67. 'showOptionMenu',
  68. 'closeWindow',
  69. 'scanQRCode',
  70. 'chooseWXPay',
  71. 'openProductSpecificView',
  72. 'addCard',
  73. 'chooseCard',
  74. 'openCard'
  75. ]
  76. });
  77. //wx.error(function (res) {
  78. // alert("错误:" + res);
  79. //});
  80. wx.checkJsApi({
  81. jsApiList: [
  82. 'getLocation',
  83. ],
  84. success: function (res) {
  85. if (res.checkResult.getLocation == false) {
  86. alert('你的微信版本太低,不支持微信JS接口,请升级到最新的微信版本!');
  87. return;
  88. }
  89. }
  90. });
  91. wx.ready(function () {
  92. wx.getLocation({
  93. type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
  94. success: function (res) {
  95. var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
  96. var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
  97. var speed = res.speed; // 速度,以米/每秒计
  98. var accuracy = res.accuracy; // 位置精度
  99. //alert(latitude + "。" + longitude);
  100. //获取到经纬度之后,异步去后台加载出来真实的地理位置
  101. $.post("/App/Common/GetLocation", { lat: latitude, lon: longitude },
  102. function (data) {
  103. //把返回回来的地理位置显示在页面的控件里面
  104. $("#txt_dw").val(data);
  105. }, 'html');
  106. },
  107. cancel: function (res) {
  108. alert('用户拒绝授权获取地理位置');
  109. }
  110. });
  111. });
  112. </script>
  113. }
复制代码

2.

  1. /// <summary>
  2. /// 微信定位
  3. /// </summary>
  4. /// <returns></returns>
  5. public ActionResult WX_Location()
  6. {
  7. #region 获取定位所需要的参数
  8. //jssdk JS接口安全域名填写,
  9. //access_token来获取jsapi_ticket
  10. string ticket = GetTicket();
  11. var timeStamp = TenpayUtil.getTimestamp();
  12. var nonceStr = TenpayUtil.getNoncestr();
  13. //设置参数
  14. RequestHandler paySignReqHandler = new RequestHandler(System.Web.HttpContext.Current);
  15. //参数顺序。
  16. paySignReqHandler.setParameter("jsapi_ticket", ticket);
  17. paySignReqHandler.setParameter("noncestr", nonceStr);
  18. paySignReqHandler.setParameter("timestamp", timeStamp);
  19. paySignReqHandler.setParameter("url", Request.Url.AbsoluteUri);//Url#号后不要
  20. // LogHelper.WriteInfoLog("noncestr:" + nonceStr + "。jsapi_ticked:" + ticket + "。timestamp:" + timeStamp + "。url:"+Request.Url.AbsoluteUri + "。");
  21. ViewData["signature"] = paySignReqHandler.createSHA1Sign();
  22. //LogHelper.WriteInfoLog("signature:" + paySignReqHandler.createSHA1Sign());
  23. ViewData["timestamp"] = timeStamp;
  24. ViewData["nonceStr"] = nonceStr;
  25. #endregion
  26. return View();
  27. }
复制代码

3. 获取地理位置方法

  1. #region 获取地理位置
  2. public ActionResult GetLocation(string lat, string lon)
  3. {
  4. //23.1294。113.3761
  5. LogHelper.WriteInfoLog(lat + "。" + lon);
  6. string x = string.Empty, y = string.Empty, strReturn = string.Empty;
  7. #region 先把微信经纬度(23.12536。113.36684 )转换成百度坐标
  8. string apiurl = "http://api.map./geoconv/v1/?coords=" + lon + "," + lat + "&from=1&to=5&ak=你的百度地图api密钥";
  9. WebRequest request = WebRequest.Create(@apiurl);
  10. request.Method = "POST";
  11. WebResponse response = request.GetResponse();
  12. Stream stream = response.GetResponseStream();
  13. Encoding encode = Encoding.UTF8;
  14. StreamReader reader = new StreamReader(stream, encode);
  15. string detail = reader.ReadToEnd();
  16. var jd = JsonConvert.DeserializeObject<BaiDuCoordinates>(detail);
  17. List<bc_result> result = jd.result;
  18. foreach (var item in result)
  19. {
  20. x = item.x;
  21. y = item.y;
  22. }
  23. #endregion
  24. #region 通过得到的百度坐标进行逆地址解析获取到真实的地理位置
  25. apiurl = "http://api.map./geocoder/v2/?ak=8aoCgAGfz0r4MantipNitjI0&callback=renderReverse&location=" + y + "," + x + "&output=json&pois=1";
  26. #region 通过传入的参数得到url请求
  27. request = WebRequest.Create(@apiurl);
  28. request.Method = "POST";
  29. response = request.GetResponse();
  30. stream = response.GetResponseStream();
  31. encode = Encoding.UTF8;
  32. reader = new StreamReader(stream, encode);
  33. detail = reader.ReadToEnd();
  34. //@"(?is)(?<=)(.?)(?=)";//(?is)
  35. // string results = System.Text.RegularExpressions.Regex.Replace(detail, @"(?is)(?<=)(.?)(?=)", "$2");
  36. string results = Regex.Match(detail, @"(?is)(?<=)(.?)(?=)").Result("$1");
  37. JsonData jsondta = JsonMapper.ToObject(results);
  38. JsonData jdItems = jsondta["result"];
  39. //获取结构化地址信息
  40. strReturn = (String)jdItems["formatted_address"];
  41. LogHelper.WriteInfoLog(strReturn);
  42. #endregion
  43. #endregion
  44. return Content(strReturn);
  45. }
  46. #endregion
复制代码

涉及到的相关方法以及类:

1. 获取ticket

  1. #region w微信JS-SDK权限签名
  2. public string GetTicket()
  3. {
  4. #region 通过 appid + appsecert 获取公众号的 access_token(不是用户的 access_token)
  5. string apiurl = "https://api.weixin./cgi-bin/token?grant_type=client_credential&appid=" + TenpayUtil.appid + "&secret=" + TenpayUtil.appsecret;
  6. #region 通过传入的参数得到url请求
  7. WebRequest request = WebRequest.Create(@apiurl);
  8. request.Method = "POST";
  9. WebResponse response = request.GetResponse();
  10. Stream stream = response.GetResponseStream();
  11. Encoding encode = Encoding.UTF8;
  12. StreamReader reader = new StreamReader(stream, encode);
  13. string detail = reader.ReadToEnd();
  14. var jd = JsonConvert.DeserializeObject<WX_JSSDK>(detail);
  15. String access_token = (String)jd.access_token;
  16. Session["access_token"] = access_token;
  17. #endregion
  18. #endregion
  19. #region 获取ticket
  20. apiurl = "https://api.weixin./cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi";
  21. request = WebRequest.Create(@apiurl);
  22. response = request.GetResponse();
  23. stream = response.GetResponseStream();
  24. encode = Encoding.UTF8;
  25. reader = new StreamReader(stream, encode);
  26. detail = reader.ReadToEnd();
  27. jd = JsonConvert.DeserializeObject<WX_JSSDK>(detail);
  28. String ticket = jd.ticket;
  29. Session["ticket"] = ticket;
  30. #endregion
  31. return ticket;
  32. }
  33. #endregion
复制代码

2. TenpayUtil类

  1. /// <summary>
  2. /// TenpayUtil 的摘要说明。
  3. /// 配置文件
  4. /// </summary>
  5. public class TenpayUtil
  6. {
  7. public static string tenpay = "1";
  8. //财付通商户号
  9. public static string partner = "";/
  10. //财付通密钥
  11. public static string key = "";
  12. //微信appsecret
  13. public static string appsecret = "";
  14. //微信appid
  15. public static string appid = "";
  16. //paysignkey(非appkey)
  17. public static string appkey = "";
  18. //支付完成后的回调处理页面,*替换成notify_url.asp所在路径
  19. public static string tenpay_notify = "";
  20. public TenpayUtil()
  21. {
  22. }
  23. public static string getNoncestr()
  24. {
  25. Random random = new Random();
  26. return MD5Util.GetMD5(random.Next(1000).ToString(), "GBK");
  27. }
  28. public static string getTimestamp()
  29. {
  30. TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
  31. return Convert.ToInt64(ts.TotalSeconds).ToString();
  32. }
  33. /** 对字符串进行URL编码 */
  34. public static string UrlEncode(string instr, string charset)
  35. {
  36. //return instr;
  37. if (instr == null || instr.Trim() == "")
  38. return "";
  39. else
  40. {
  41. string res;
  42. try
  43. {
  44. res = HttpUtility.UrlEncode(instr, Encoding.GetEncoding(charset));
  45. }
  46. catch (Exception ex)
  47. {
  48. res = HttpUtility.UrlEncode(instr, Encoding.GetEncoding("GB2312"));
  49. }
  50. return res;
  51. }
  52. }
  53. /** 对字符串进行URL解码 */
  54. public static string UrlDecode(string instr, string charset)
  55. {
  56. if (instr == null || instr.Trim() == "")
  57. return "";
  58. else
  59. {
  60. string res;
  61. try
  62. {
  63. res = HttpUtility.UrlDecode(instr, Encoding.GetEncoding(charset));
  64. }
  65. catch (Exception ex)
  66. {
  67. res = HttpUtility.UrlDecode(instr, Encoding.GetEncoding("GB2312"));
  68. }
  69. return res;
  70. }
  71. }
  72. /** 取时间戳生成随即数,替换交易单号中的后10位流水号 */
  73. public static UInt32 UnixStamp()
  74. {
  75. TimeSpan ts = DateTime.Now - TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
  76. return Convert.ToUInt32(ts.TotalSeconds);
  77. }
  78. /** 取随机数 */
  79. public static string BuildRandomStr(int length)
  80. {
  81. Random rand = new Random();
  82. int num = rand.Next();
  83. string str = num.ToString();
  84. if (str.Length > length)
  85. {
  86. str = str.Substring(0, length);
  87. }
  88. else if (str.Length < length)
  89. {
  90. int n = length - str.Length;
  91. while (n > 0)
  92. {
  93. str.Insert(0, "0");
  94. n--;
  95. }
  96. }
  97. return str;
  98. }
  99. }
复制代码

3. RequestHandler类

  1. /**
  2. '签名工具类
  3. ============================================================================/// <summary>
  4. 'api说明:
  5. 'init();
  6. '初始化函数,默认给一些参数赋值。
  7. 'setKey(key_)'设置商户密钥
  8. 'createMd5Sign(signParams);字典生成Md5签名
  9. 'genPackage(packageParams);获取package包
  10. 'createSHA1Sign(signParams);创建签名SHA1
  11. 'parseXML();输出xml
  12. 'getDebugInfo(),获取debug信息
  13. *
  14. * ============================================================================
  15. */
  16. public class RequestHandler
  17. {
  18. public RequestHandler(HttpContext httpContext)
  19. {
  20. parameters = new Hashtable();
  21. this.httpContext = httpContext;
  22. }
  23. /** 密钥 */
  24. private string key;
  25. protected HttpContext httpContext;
  26. /** 请求的参数 */
  27. protected Hashtable parameters;
  28. /** debug信息 */
  29. private string debugInfo;
  30. /** 初始化函数 */
  31. public virtual void init()
  32. {
  33. }
  34. /** 获取debug信息 */
  35. public String getDebugInfo()
  36. {
  37. return debugInfo;
  38. }
  39. /** 获取密钥 */
  40. public String getKey()
  41. {
  42. return key;
  43. }
  44. /** 设置密钥 */
  45. public void setKey(string key)
  46. {
  47. this.key = key;
  48. }
  49. /** 设置参数值 */
  50. public void setParameter(string parameter, string parameterValue)
  51. {
  52. if (parameter != null && parameter != "")
  53. {
  54. if (parameters.Contains(parameter))
  55. {
  56. parameters.Remove(parameter);
  57. }
  58. parameters.Add(parameter, parameterValue);
  59. }
  60. }
  61. //获取package带参数的签名包
  62. public string getRequestURL()
  63. {
  64. this.createSign();
  65. StringBuilder sb = new StringBuilder();
  66. ArrayList akeys = new ArrayList(parameters.Keys);
  67. akeys.Sort();
  68. foreach (string k in akeys)
  69. {
  70. string v = (string)parameters[k];
  71. if (null != v && "key".CompareTo(k) != 0)
  72. {
  73. sb.Append(k + "=" + TenpayUtil.UrlEncode(v, getCharset()) + "&");
  74. }
  75. }
  76. //去掉最后一个&
  77. if (sb.Length > 0)
  78. {
  79. sb.Remove(sb.Length - 1, 1);
  80. }
  81. return sb.ToString();
  82. }
  83. //创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
  84. protected virtual void createSign()
  85. {
  86. StringBuilder sb = new StringBuilder();
  87. ArrayList akeys = new ArrayList(parameters.Keys);
  88. akeys.Sort();
  89. foreach (string k in akeys)
  90. {
  91. string v = (string)parameters[k];
  92. if (null != v && "".CompareTo(v) != 0
  93. && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0)
  94. {
  95. sb.Append(k + "=" + v + "&");
  96. }
  97. }
  98. sb.Append("key=" + this.getKey());
  99. string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToUpper();
  100. this.setParameter("sign", sign);
  101. //debug信息
  102. this.setDebugInfo(sb.ToString() + " => sign:" + sign);
  103. }
  104. //创建package签名
  105. public virtual string CreateMd5Sign(string key, string value)
  106. {
  107. StringBuilder sb = new StringBuilder();
  108. ArrayList akeys = new ArrayList(parameters.Keys);
  109. akeys.Sort();
  110. foreach (string k in akeys)
  111. {
  112. string v = (string)parameters[k];
  113. if (null != v && "".CompareTo(v) != 0
  114. && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0)
  115. {
  116. sb.Append(k + "=" + v + "&");
  117. }
  118. }
  119. sb.Append(key + "=" + value);
  120. string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToUpper();
  121. return sign;
  122. }
  123. //创建sha1签名
  124. public string createSHA1Sign()
  125. {
  126. StringBuilder sb = new StringBuilder();
  127. ArrayList akeys = new ArrayList(parameters.Keys);
  128. akeys.Sort();
  129. foreach (string k in akeys)
  130. {
  131. string v = (string)parameters[k];
  132. if (null != v && "".CompareTo(v) != 0
  133. && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0)
  134. {
  135. if (sb.Length == 0)
  136. {
  137. sb.Append(k + "=" + v);
  138. }
  139. else
  140. {
  141. sb.Append("&" + k + "=" + v);
  142. }
  143. }
  144. }
  145. string paySign = SHA1Util.getSha1(sb.ToString()).ToString().ToLower();
  146. //debug信息
  147. this.setDebugInfo(sb.ToString() + " => sign:" + paySign);
  148. return paySign;
  149. }
  150. public string GetBizSign()
  151. {
  152. Dictionary<string, string> bizParameters = new Dictionary<string, string>();
  153. ArrayList akeys = new ArrayList(parameters.Keys);
  154. akeys.Sort();
  155. foreach (string k in akeys)
  156. {
  157. string v = (string)parameters[k];
  158. if (!string.IsNullOrEmpty(k))
  159. {
  160. bizParameters.Add(k.ToLower(), v);
  161. }
  162. }
  163. if (!bizParameters.Any(p => p.Key.ToLower() == "appkey"))
  164. bizParameters.Add("appkey", TenpayUtil.appkey);
  165. string bizString = FormatBizQueryParaMap(bizParameters, false);
  166. return SHA1Util.Sha1(bizString);
  167. }
  168. public string FormatBizQueryParaMap(Dictionary<string, string> paraMap, bool urlencode)
  169. {
  170. string buff = "";
  171. try
  172. {
  173. var result = from pair in paraMap orderby pair.Key select pair;
  174. foreach (KeyValuePair<string, string> pair in result)
  175. {
  176. if (pair.Key != "")
  177. {
  178. string key = pair.Key;
  179. string val = pair.Value;
  180. if (urlencode)
  181. {
  182. val = System.Web.HttpUtility.UrlEncode(val);
  183. }
  184. buff += key.ToLower() + "=" + val + "&";
  185. }
  186. }
  187. if (buff.Length == 0 == false)
  188. {
  189. buff = buff.Substring(0, (buff.Length - 1) - (0));
  190. }
  191. }
  192. catch (Exception e)
  193. {
  194. throw e;
  195. //throw new SDKRuntimeException(e.Message);
  196. }
  197. return buff;
  198. }
  199. //输出XML
  200. public string parseXML()
  201. {
  202. StringBuilder sb = new StringBuilder();
  203. sb.Append("<xml>");
  204. int iIsNumber = 0;
  205. foreach (string k in parameters.Keys)
  206. {
  207. string v = (string)parameters[k];
  208. if (int.TryParse(v, out iIsNumber))
  209. {
  210. sb.Append("<" + k + ">" + v + "</" + k + ">");
  211. }
  212. else
  213. {
  214. sb.Append("<" + k + "><![CDATA[" + v + "]]></" + k + ">");
  215. }
  216. }
  217. sb.Append("</xml>");
  218. return sb.ToString();
  219. }
  220. /** 设置debug信息 */
  221. public void setDebugInfo(String debugInfo)
  222. {
  223. this.debugInfo = debugInfo;
  224. }
  225. public Hashtable getAllParameters()
  226. {
  227. return this.parameters;
  228. }
  229. protected virtual string getCharset()
  230. {
  231. return this.httpContext.Request.ContentEncoding.BodyName;
  232. }
  233. }
复制代码

4. 实体

  1. #region 微信sdk
  2. public partial class WX_JSSDK
  3. {
  4. public string access_token { get; set; }
  5. public string ticket { get; set; }
  6. }
  7. #endregion
  8. #region 百度坐标转换
  9. public partial class BaiDuCoordinates
  10. {
  11. public string status { get; set; }
  12. public List<bc_result> result { get; set; }
  13. }
  14. public partial class bc_result
  15. {
  16. public string x { get; set; }
  17. public string y { get; set; }
  18. }
  19. #endregion
复制代码

更多关于C#相关内容感兴趣的读者可查看本站专题:《C#常见控件用法教程》、《WinForm控件用法总结》、《C#数据结构与算法教程》、《C#面向对象程序设计入门教程》及《C#程序设计之线程使用技巧总结》

希望本文所述对大家C#程序设计有所帮助。

您可能感兴趣的文章:

  • c#封装百度web服务geocoding api 、百度坐标转换示例
  • C#实现解析百度天气数据,Rss解析百度新闻以及根据IP获取所在城市的方法
  • C#微信公众号开发之接收事件推送与消息排重的方法
  • C#实现百度网站收录和排名查询功能思路及实例
  • C#开发微信公众号接口开发
  • 如何根据百度地图计算出两地之间的驾驶距离(两种语言js和C#)
  • C#微信公众平台开发之access_token的获取存储与更新
  • C#微信公众平台开发之高级群发接口
  • C#.net 微信公众账号接口开发
  • C#实现百度ping推送功能的方法
  • C#微信开发之获取接口调用凭据
  • C#微信小程序服务端获取用户解密信息实例代码


回复

使用道具 举报