Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
257 views
in Technique[技术] by (71.8m points)

c# - Consuming a REST XML web service

I'm trying to consume the following web service http://ipinfodb.com/ip_location_api.php this web service returns an xml response, the code below gets the XML response, but somehow when phasing the values from the XML response it does not work.

What is wrong with my code?

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();
    }
}

}

EDIT: this is the XML response returned

  <?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>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

My solution would be:

  • run the xsd.exe utility on your result XML twice to convert it to a XSD (first step) and a C# class (second step) - this would give you a C# class Response

  • next, you can easily deserialize the response into an instance of that class:

    HttpWebRequest request = WebRequest.Create("http://api.ipinfodb.com/v2/ip_query.php?key=--yourkey--&ip=74.125.45.100&timezone=true") as HttpWebRequest;
    
    XmlSerializer ser = new XmlSerializer(typeof(Response));
    
    WebResponse response = request.GetResponse();
    var result = ser.Deserialize(response.GetResponseStream());
    

    and now your result would contain an instance of Response, with all the elements as nice fields in your object.

Read more about xsd.exe on its MSDN doc page.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...