C#实现微信结合百度api获取当前用户地理位置的方法
本文实例讲述了C#实现微信结合百度api获取当前用户地理位置的方法。分享给大家供大家参考,具体如下:
操作步骤:
1. 先根据微信提供的接口文档获取到经纬度
参考文档地址:http://mp.weixin.qq.com/wiki/8/1b86529d05db9f960e48c3c7ca5be288.html
2. 由于直接使用微信获取到的经纬度,来使用百度地图api获取地址存在500~1000米的偏差,有时候定位不是很准确,所以需要转换成百度的坐标
参考文档地址:http://developer.baidu.com/map/index.php?title=webapi/guide/changeposition
3. 根据百度api实现逆地址解析,获取当前位置
参考文档地址:http://developer.baidu.com/map/index.php?title=webapi/guide/webservice-geocoding
具体实例:
该例子是mvc项目
1. WX_Location.cshtml页面:
@using System.Web.Optimization; @{ Layout = "~/Views/Shared/Master/_App.cshtml"; } @section Head{ } <div data-role="page"> <div data-role="header" id="header" data-position="fixed"> <h1>微信定位页面</h1> </div> <div data-role="content" class="ui-content"> <form id="add" method="post" onsubmit="return false"> <table border="0" cellpadding="0" cellspacing="0" class="register_table"> <tr class='tr_bg neiy'> <td class='tdl neiy'>定位:</td> <td class='tdr'><input id='txt_dw' name='dw' type='text' placeholder='正在定位' class='td_input' value='' /></td></tr> </table> <div data-role="footer" data-position="fixed" data-id="footernav"> <div data-role="navbar"> <ul> <li><a href="" style=" rel="external nofollow" font-size: 1em;">返回主页</a></li> </ul> </div> </div> @Html.AntiForgeryToken() </form> </div> </div> @section scripts{ @*微信js-sdk*@ <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js" type="text/javascript"></script> <script type="text/javascript"> //微信jssdk配置 wx.config({ debug: false, appId: "", timestamp: "@Html.Raw(ViewData["timestamp"])", nonceStr: "@Html.Raw(ViewData["nonceStr"])", signature: "@Html.Raw(ViewData["signature"])", jsApiList: [ 'checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'hideMenuItems', 'showMenuItems', 'hideAllNonBaseMenuItem', 'showAllNonBaseMenuItem', 'translateVoice', 'startRecord', 'stopRecord', 'onRecordEnd', 'playVoice', 'pauseVoice', 'stopVoice', 'uploadVoice', 'downloadVoice', 'chooseImage', 'previewImage', 'uploadImage', 'downloadImage', 'getNetworkType', 'openLocation', 'getLocation', 'hideOptionMenu', 'showOptionMenu', 'closeWindow', 'scanQRCode', 'chooseWXPay', 'openProductSpecificView', 'addCard', 'chooseCard', 'openCard' ] }); //wx.error(function (res) { // alert("错误:" + res); //}); wx.checkJsApi({ jsApiList: [ 'getLocation', ], success: function (res) { if (res.checkResult.getLocation == false) { alert('你的微信版本太低,不支持微信JS接口,请升级到最新的微信版本!'); return; } } }); wx.ready(function () { wx.getLocation({ type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02' success: function (res) { var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90 var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。 var speed = res.speed; // 速度,以米/每秒计 var accuracy = res.accuracy; // 位置精度 //alert(latitude + "。" + longitude); //获取到经纬度之后,异步去后台加载出来真实的地理位置 $.post("/App/Common/GetLocation", { lat: latitude, lon: longitude }, function (data) { //把返回回来的地理位置显示在页面的控件里面 $("#txt_dw").val(data); }, 'html'); }, cancel: function (res) { alert('用户拒绝授权获取地理位置'); } }); }); </script> }
2.
/// <summary> /// 微信定位 /// </summary> /// <returns></returns> public ActionResult WX_Location() { #region 获取定位所需要的参数 //jssdk JS接口安全域名填写, //access_token来获取jsapi_ticket string ticket = GetTicket(); var timeStamp = TenpayUtil.getTimestamp(); var nonceStr = TenpayUtil.getNoncestr(); //设置参数 RequestHandler paySignReqHandler = new RequestHandler(System.Web.HttpContext.Current); //参数顺序。 paySignReqHandler.setParameter("jsapi_ticket", ticket); paySignReqHandler.setParameter("noncestr", nonceStr); paySignReqHandler.setParameter("timestamp", timeStamp); paySignReqHandler.setParameter("url", Request.Url.AbsoluteUri);//Url#号后不要 // LogHelper.WriteInfoLog("noncestr:" + nonceStr + "。jsapi_ticked:" + ticket + "。timestamp:" + timeStamp + "。url:"+Request.Url.AbsoluteUri + "。"); ViewData["signature"] = paySignReqHandler.createSHA1Sign(); //LogHelper.WriteInfoLog("signature:" + paySignReqHandler.createSHA1Sign()); ViewData["timestamp"] = timeStamp; ViewData["nonceStr"] = nonceStr; #endregion return View(); }
3. 获取地理位置方法
#region 获取地理位置 public ActionResult GetLocation(string lat, string lon) { //23.1294。113.3761 LogHelper.WriteInfoLog(lat + "。" + lon); string x = string.Empty, y = string.Empty, strReturn = string.Empty; #region 先把微信经纬度(23.12536。113.36684 )转换成百度坐标 string apiurl = "http://api.map.baidu.com/geoconv/v1/?coords=" + lon + "," + lat + "&from=1&to=5&ak=你的百度地图api密钥"; WebRequest request = WebRequest.Create(@apiurl); request.Method = "POST"; WebResponse response = request.GetResponse(); Stream stream = response.GetResponseStream(); Encoding encode = Encoding.UTF8; StreamReader reader = new StreamReader(stream, encode); string detail = reader.ReadToEnd(); var jd = JsonConvert.DeserializeObject<BaiDuCoordinates>(detail); List<bc_result> result = jd.result; foreach (var item in result) { x = item.x; y = item.y; } #endregion #region 通过得到的百度坐标进行逆地址解析获取到真实的地理位置 apiurl = "http://api.map.baidu.com/geocoder/v2/?ak=8aoCgAGfz0r4MantipNitjI0&callback=renderReverse&location=" + y + "," + x + "&output=json&pois=1"; #region 通过传入的参数得到url请求 request = WebRequest.Create(@apiurl); request.Method = "POST"; response = request.GetResponse(); stream = response.GetResponseStream(); encode = Encoding.UTF8; reader = new StreamReader(stream, encode); detail = reader.ReadToEnd(); //@"(?is)(?<=)(.∗)(?=)";//(?is) // string results = System.Text.RegularExpressions.Regex.Replace(detail, @"(?is)(?<=)(.∗)(?=)", "$2"); string results = Regex.Match(detail, @"(?is)(?<=)(.∗)(?=)").Result("$1"); JsonData jsondta = JsonMapper.ToObject(results); JsonData jdItems = jsondta["result"]; //获取结构化地址信息 strReturn = (String)jdItems["formatted_address"]; LogHelper.WriteInfoLog(strReturn); #endregion #endregion return Content(strReturn); } #endregion
涉及到的相关方法以及类:
1. 获取ticket
#region w微信JS-SDK权限签名 public string GetTicket() { #region 通过 appid + appsecert 获取公众号的 access_token(不是用户的 access_token) string apiurl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + TenpayUtil.appid + "&secret=" + TenpayUtil.appsecret; #region 通过传入的参数得到url请求 WebRequest request = WebRequest.Create(@apiurl); request.Method = "POST"; WebResponse response = request.GetResponse(); Stream stream = response.GetResponseStream(); Encoding encode = Encoding.UTF8; StreamReader reader = new StreamReader(stream, encode); string detail = reader.ReadToEnd(); var jd = JsonConvert.DeserializeObject<WX_JSSDK>(detail); String access_token = (String)jd.access_token; Session["access_token"] = access_token; #endregion #endregion #region 获取ticket apiurl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi"; request = WebRequest.Create(@apiurl); response = request.GetResponse(); stream = response.GetResponseStream(); encode = Encoding.UTF8; reader = new StreamReader(stream, encode); detail = reader.ReadToEnd(); jd = JsonConvert.DeserializeObject<WX_JSSDK>(detail); String ticket = jd.ticket; Session["ticket"] = ticket; #endregion return ticket; } #endregion
2. TenpayUtil类
/// <summary> /// TenpayUtil 的摘要说明。 /// 配置文件 /// </summary> public class TenpayUtil { public static string tenpay = "1"; //财付通商户号 public static string partner = "";/ //财付通密钥 public static string key = ""; //微信appsecret public static string appsecret = ""; //微信appid public static string appid = ""; //paysignkey(非appkey) public static string appkey = ""; //支付完成后的回调处理页面,*替换成notify_url.asp所在路径 public static string tenpay_notify = ""; public TenpayUtil() { } public static string getNoncestr() { Random random = new Random(); return MD5Util.GetMD5(random.Next(1000).ToString(), "GBK"); } public static string getTimestamp() { TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalSeconds).ToString(); } /** 对字符串进行URL编码 */ public static string UrlEncode(string instr, string charset) { //return instr; if (instr == null || instr.Trim() == "") return ""; else { string res; try { res = HttpUtility.UrlEncode(instr, Encoding.GetEncoding(charset)); } catch (Exception ex) { res = HttpUtility.UrlEncode(instr, Encoding.GetEncoding("GB2312")); } return res; } } /** 对字符串进行URL解码 */ public static string UrlDecode(string instr, string charset) { if (instr == null || instr.Trim() == "") return ""; else { string res; try { res = HttpUtility.UrlDecode(instr, Encoding.GetEncoding(charset)); } catch (Exception ex) { res = HttpUtility.UrlDecode(instr, Encoding.GetEncoding("GB2312")); } return res; } } /** 取时间戳生成随即数,替换交易单号中的后10位流水号 */ public static UInt32 UnixStamp() { TimeSpan ts = DateTime.Now - TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); return Convert.ToUInt32(ts.TotalSeconds); } /** 取随机数 */ public static string BuildRandomStr(int length) { Random rand = new Random(); int num = rand.Next(); string str = num.ToString(); if (str.Length > length) { str = str.Substring(0, length); } else if (str.Length < length) { int n = length - str.Length; while (n > 0) { str.Insert(0, "0"); n--; } } return str; } }
3. RequestHandler类
/** '签名工具类 ============================================================================/// <summary> 'api说明: 'init(); '初始化函数,默认给一些参数赋值。 'setKey(key_)'设置商户密钥 'createMd5Sign(signParams);字典生成Md5签名 'genPackage(packageParams);获取package包 'createSHA1Sign(signParams);创建签名SHA1 'parseXML();输出xml 'getDebugInfo(),获取debug信息 * * ============================================================================ */ public class RequestHandler { public RequestHandler(HttpContext httpContext) { parameters = new Hashtable(); this.httpContext = httpContext; } /** 密钥 */ private string key; protected HttpContext httpContext; /** 请求的参数 */ protected Hashtable parameters; /** debug信息 */ private string debugInfo; /** 初始化函数 */ public virtual void init() { } /** 获取debug信息 */ public String getDebugInfo() { return debugInfo; } /** 获取密钥 */ public String getKey() { return key; } /** 设置密钥 */ public void setKey(string key) { this.key = key; } /** 设置参数值 */ public void setParameter(string parameter, string parameterValue) { if (parameter != null && parameter != "") { if (parameters.Contains(parameter)) { parameters.Remove(parameter); } parameters.Add(parameter, parameterValue); } } //获取package带参数的签名包 public string getRequestURL() { this.createSign(); StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(parameters.Keys); akeys.Sort(); foreach (string k in akeys) { string v = (string)parameters[k]; if (null != v && "key".CompareTo(k) != 0) { sb.Append(k + "=" + TenpayUtil.UrlEncode(v, getCharset()) + "&"); } } //去掉最后一个& if (sb.Length > 0) { sb.Remove(sb.Length - 1, 1); } return sb.ToString(); } //创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。 protected virtual void createSign() { StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(parameters.Keys); akeys.Sort(); foreach (string k in akeys) { string v = (string)parameters[k]; if (null != v && "".CompareTo(v) != 0 && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0) { sb.Append(k + "=" + v + "&"); } } sb.Append("key=" + this.getKey()); string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToUpper(); this.setParameter("sign", sign); //debug信息 this.setDebugInfo(sb.ToString() + " => sign:" + sign); } //创建package签名 public virtual string CreateMd5Sign(string key, string value) { StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(parameters.Keys); akeys.Sort(); foreach (string k in akeys) { string v = (string)parameters[k]; if (null != v && "".CompareTo(v) != 0 && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0) { sb.Append(k + "=" + v + "&"); } } sb.Append(key + "=" + value); string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToUpper(); return sign; } //创建sha1签名 public string createSHA1Sign() { StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(parameters.Keys); akeys.Sort(); foreach (string k in akeys) { string v = (string)parameters[k]; if (null != v && "".CompareTo(v) != 0 && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0) { if (sb.Length == 0) { sb.Append(k + "=" + v); } else { sb.Append("&" + k + "=" + v); } } } string paySign = SHA1Util.getSha1(sb.ToString()).ToString().ToLower(); //debug信息 this.setDebugInfo(sb.ToString() + " => sign:" + paySign); return paySign; } public string GetBizSign() { Dictionary<string, string> bizParameters = new Dictionary<string, string>(); ArrayList akeys = new ArrayList(parameters.Keys); akeys.Sort(); foreach (string k in akeys) { string v = (string)parameters[k]; if (!string.IsNullOrEmpty(k)) { bizParameters.Add(k.ToLower(), v); } } if (!bizParameters.Any(p => p.Key.ToLower() == "appkey")) bizParameters.Add("appkey", TenpayUtil.appkey); string bizString = FormatBizQueryParaMap(bizParameters, false); return SHA1Util.Sha1(bizString); } public string FormatBizQueryParaMap(Dictionary<string, string> paraMap, bool urlencode) { string buff = ""; try { var result = from pair in paraMap orderby pair.Key select pair; foreach (KeyValuePair<string, string> pair in result) { if (pair.Key != "") { string key = pair.Key; string val = pair.Value; if (urlencode) { val = System.Web.HttpUtility.UrlEncode(val); } buff += key.ToLower() + "=" + val + "&"; } } if (buff.Length == 0 == false) { buff = buff.Substring(0, (buff.Length - 1) - (0)); } } catch (Exception e) { throw e; //throw new SDKRuntimeException(e.Message); } return buff; } //输出XML public string parseXML() { StringBuilder sb = new StringBuilder(); sb.Append("<xml>"); int iIsNumber = 0; foreach (string k in parameters.Keys) { string v = (string)parameters[k]; if (int.TryParse(v, out iIsNumber)) { sb.Append("<" + k + ">" + v + "</" + k + ">"); } else { sb.Append("<" + k + "><![CDATA[" + v + "]]></" + k + ">"); } } sb.Append("</xml>"); return sb.ToString(); } /** 设置debug信息 */ public void setDebugInfo(String debugInfo) { this.debugInfo = debugInfo; } public Hashtable getAllParameters() { return this.parameters; } protected virtual string getCharset() { return this.httpContext.Request.ContentEncoding.BodyName; } }
4. 实体
#region 微信sdk public partial class WX_JSSDK { public string access_token { get; set; } public string ticket { get; set; } } #endregion #region 百度坐标转换 public partial class BaiDuCoordinates { public string status { get; set; } public List<bc_result> result { get; set; } } public partial class bc_result { public string x { get; set; } public string y { get; set; } } #endregion
更多关于C#相关内容感兴趣的读者可查看本站专题:《C#常见控件用法教程》、《WinForm控件用法总结》、《C#数据结构与算法教程》、《C#面向对象程序设计入门教程》及《C#程序设计之线程使用技巧总结》
希望本文所述对大家C#程序设计有所帮助。
相关文章
- 这篇文章主要介绍了C# 字段和属性的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下...2020-11-03
- 我们在使用C#做项目的时候,基本上都需要制作登录界面,那么今天我们就来一步步看看,如果简单的实现登录界面呢,本文给出2个例子,由简入难,希望大家能够喜欢。...2020-06-25
- 这篇文章主要介绍了C#中截取字符串的的基本方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-03
- 这篇文章主要介绍了C#实现简单的Http请求的方法,以实例形式较为详细的分析了C#实现Http请求的具体方法,需要的朋友可以参考下...2020-06-25
- 本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
- 本文主要介绍了C#中new的几种用法,具有很好的参考价值,下面跟着小编一起来看下吧...2020-06-25
使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序)
这篇文章主要介绍了使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25- 这篇文章主要介绍了C#开发Windows窗体应用程序的简单操作步骤,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
- 专做了百度和google的网盟推广以作推广效果的评估比较。百度的周期为6天,google为4天。 从百度的统计数据可以看出这六天的点击次数总共为464,平均点击花费了0.30元...2017-07-06
- 这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
- 最近做一个小项目不可避免的需要前端脚本与后台进行交互。由于是在asp.net中实现,故问题演化成asp.net中jiavascript与后台c#如何进行交互。...2020-06-25
- 本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
- 轻松学习C#的基础入门,了解C#最基本的知识点,C#是一种简洁的,类型安全的一种完全面向对象的开发语言,是Microsoft专门基于.NET Framework平台开发的而量身定做的高级程序设计语言,需要的朋友可以参考下...2020-06-25
- 本文主要介绍了C#变量命名规则小结,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-09
- 这篇文章主要介绍了C#绘制曲线图的方法,以完整实例形式较为详细的分析了C#进行曲线绘制的具体步骤与相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
- 本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
- 这篇文章主要介绍了c#自带缓存使用方法,包括获取数据缓存、设置数据缓存、移除指定数据缓存等方法,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了c#中(&&,||)与(&,|)的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
- 下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
- 这篇文章主要用实例讲解C#递归算法的概念以及用法,文中代码非常详细,帮助大家更好的参考和学习,感兴趣的朋友可以了解下...2020-06-25