我正在尝试使用以下Web服务
http://ipinfodb.com/ip_location_api.php
此Web服务返回一个xml响应,下面的代码可以获得XML响应,但是当从XML响应中分阶段处理时它不起作用.
此Web服务返回一个xml响应,下面的代码可以获得XML响应,但是当从XML响应中分阶段处理时它不起作用.
我的代码有什么问题?
using System; using System.Collections.Generic; using System.Text; using System.Web; using System.IO; using System.Net; using System.Xml; namespace ConsoleApplication3 { class Program { static void Main(string[] args) { HttpWebRequest request = null; HttpWebResponse response = null; String Xml; // Create the web request request = WebRequest.Create("http://api.ipinfodb.com/v2/ip_query.PHP?key=<yourkey>&ip=74.125.45.100&timezone=true") as HttpWebRequest; // Get response using (response = request.GetResponse() as HttpWebResponse) { // Get the response stream StreamReader reader = new StreamReader(response.GetResponseStream()); Xml = reader.ReadToEnd(); } // Console xml output Console.WriteLine(Xml); //see if we get the xml response,(YES we do) Console.ReadLine(); string _currentField = ""; StringReader _sr = new StringReader(Xml); XmlTextReader _xtr = new XmlTextReader(_sr); _xtr.XmlResolver = null; _xtr.WhitespaceHandling = WhitespaceHandling.None; // get the root node _xtr.Read(); if ((_xtr.NodeType == XmlNodeType.Element) && (_xtr.Name == "Response")) { while (_xtr.Read()) { if ((_xtr.NodeType == XmlNodeType.Element) && (!_xtr.IsEmptyElement)) { _currentField = _xtr.Name; _xtr.Read(); if (_xtr.NodeType == XmlNodeType.Text) { switch (_currentField) { case "Status": Console.WriteLine(_xtr.Value); //we print to console for testing purposes,normally assign it to a variable here! break; case "CountryCode": Console.WriteLine(_xtr.Value); break; case "CountryName": Console.WriteLine(_xtr.Value); break; case "RegionCode": Console.WriteLine(_xtr.Value); break; case "RegionName": Console.WriteLine(_xtr.Value); break; case "City": Console.WriteLine(_xtr.Value); break; case "ZipPostalCode": Console.WriteLine(_xtr.Value); break; case "Latitude": Console.WriteLine(_xtr.Value); break; case "Longitude": Console.WriteLine(_xtr.Value); break; case "Gmtoffset": Console.WriteLine(_xtr.Value); break; case "Dstoffset": Console.WriteLine(_xtr.Value); break; case "TimezoneName": Console.WriteLine(_xtr.Value); break; case "Isdst": Console.WriteLine(_xtr.Value); break; case "Ip": Console.WriteLine(_xtr.Value); break; default: // unknown field throw new Exception("Unknown field in response."); } } } } } Console.ReadLine(); } }
}
编辑:这是返回的XML响应
<?xml version="1.0" encoding="UTF-8" ?> - <Response> <Status>OK</Status> <CountryCode>US</CountryCode> <CountryName>United States</CountryName> <RegionCode>06</RegionCode> <RegionName>California</RegionName> <City>Mountain View</City> <ZipPostalCode>94043</ZipPostalCode> <Latitude>37.4192</Latitude> <Longitude>-122.057</Longitude> <Gmtoffset>-28800</Gmtoffset> <Dstoffset>0</Dstoffset> <TimezoneName>America/Los_Angeles</TimezoneName> <Isdst>0</Isdst> <Ip>74.125.45.100</Ip> </Response>
解决方法
我使用这个相同的API,我将响应XML加载到
XDocument中,并解析例如.
// build URL up at runtime string apiKey = ConfigurationManager.AppSettings["geoApiKey"]; string url = String.Format(ConfigurationManager.AppSettings["geoApiUrl"],apiKey,ip); WebRequest request = WebRequest.Create(url); try { WebResponse response = request.GetResponse(); using (var sr = new System.IO.StreamReader(response.GetResponseStream())) { XDocument xmlDoc = new XDocument(); try { xmlDoc = XDocument.Parse(sr.ReadToEnd()); string status = xmlDoc.Root.Element("Status").Value; Console.WriteLine("Response status: {0}",status); if (status == "OK") { // if the status is OK it's normally safe to assume the required elements // are there. However,if you want to be safe you can always check the element // exists before retrieving the value Console.WriteLine(xmlDoc.Root.Element("CountryCode").Value); Console.WriteLine(xmlDoc.Root.Element("CountryName").Value); ... } } catch (Exception) { // handle if necessary } } } catch (WebException) { // handle if necessary }
您还应该做的是引入一个自定义类,例如GeoLocationInfo并将您的代码包含在函数中. GetGeoLocation(string ip),而不是将信息写入控制台窗口,您可以填充&返回该类的实例.