C#实现微信结合百度api获取当前用户地理位置的方法
程序员文章站
2023-12-14 09:11:10
本文实例讲述了c#实现微信结合百度api获取当前用户地理位置的方法。分享给大家供大家参考,具体如下:
操作步骤:
1. 先根据微信提供的接口文档获取到经纬度
参考文档...
本文实例讲述了c#实现微信结合百度api获取当前用户地理位置的方法。分享给大家供大家参考,具体如下:
操作步骤:
1. 先根据微信提供的接口文档获取到经纬度
参考文档地址:
2. 由于直接使用微信获取到的经纬度,来使用百度地图api获取地址存在500~1000米的偏差,有时候定位不是很准确,所以需要转换成百度的坐标
参考文档地址:
3. 根据百度api实现逆地址解析,获取当前位置
参考文档地址:
具体实例:
该例子是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#程序设计有所帮助。