C# 应用程序数据的WebClient下载未将结果集返回到读卡器中

C# 应用程序数据的WebClient下载未将结果集返回到读卡器中,c#,webforms,webclient,C#,Webforms,Webclient,我在这段代码中遇到了一个主要问题,我正在尝试从基于xml的CraftyClick服务器下载一个地址列表,我正在使用webclient进行下载,但是当我转到浏览器时,数据被删除了,但是失败了 public XmlTextReader readXML(string postcode, string response, string accessCode) { //Create URL string url = $"http://pcls1.craftyclicks

我在这段代码中遇到了一个主要问题,我正在尝试从基于xml的CraftyClick服务器下载一个地址列表,我正在使用webclient进行下载,但是当我转到浏览器时,数据被删除了,但是失败了

 public XmlTextReader readXML(string postcode, string response, string accessCode)
 {
        //Create URL
        string url = $"http://pcls1.craftyclicks.co.uk/xml/rapidaddress?postcode={postcode}&response={response}&key={accessCode}";

        try
        {
            //Create WebRequest
            WebRequest request = WebRequest.Create(url);
            using (Stream responseStream = request.GetResponse().GetResponseStream())
            {
                if (responseStream != null)
                {
                    using (TextReader textReader = new StreamReader(responseStream))
                    {
                        XmlTextReader reader = new XmlTextReader(textReader);
                        Debug.Assert(reader != null, "Reader is NULL");
                        return reader;
                    }
                }
                throw new Exception("ResponseStream is NULL");
            }
        }
        catch (WebException ex)
        {
            return null;
        }
}
返回的Xml是

  <CraftyResponse><address_data_formatted><delivery_point><organisation_name>THE BAKERY</organisation_name><department_name/><line_1>1 HIGH STREET</line_1><line_2>CRAFTY VALLEY</line_2><udprn>12345678</udprn></delivery_point><delivery_point><organisation_name>FILMS R US</organisation_name><department_name/><line_1>3 HIGH STREET</line_1><line_2>CRAFTY VALLEY</line_2><udprn>12345679</udprn></delivery_point><delivery_point><organisation_name>FAMILY BUTCHER</organisation_name><department_name/><line_1>7 HIGH STREET</line_1><line_2>CRAFTY VALLEY</line_2><udprn>12345680</udprn></delivery_point><delivery_point><organisation_name/><department_name/><line_1>BIG HOUSE, HIGH STREET</line_1><line_2>CRAFTY VALLEY</line_2><udprn>12345681</udprn></delivery_point><delivery_point><organisation_name/><department_name/><line_1>LITTLE COTTAGE</line_1><line_2>17 HIGH STREET, CRAFTY VALLEY</line_2><udprn>12345682</udprn></delivery_point><delivery_point_count>5</delivery_point_count><town>BIG CITY</town><postal_county>POSTAL COUNTY</postal_county><traditional_county>TRADITIONAL COUNTY</traditional_county><postcode>AA1 1AA</postcode></address_data_formatted></CraftyResponse>
我对上述函数的调用代码是

  fhsBl.Helpers.CraftyPostCodeLookup _postCodeLookup = new fhsBl.Helpers.CraftyPostCodeLookup();

        DataTable dt = new DataTable();

       dt = _postCodeLookup.returnAddressList("AA11AA", "API KEY DONT BE NOSY");
编辑1 Ok建议我更改代码以使用using语句并读取其中的内容,但我收到另一个错误,仍然无法生成数据

 public DataTable readXML(string postcode, string response, string accessCode)
    {
        //Create URL
        string url = $"http://pcls1.craftyclicks.co.uk/xml/rapidaddress?postcode={postcode}&response={response}&key={accessCode}";

        try
        {
            DataTable dtReturn = new DataTable();
            dtReturn.Columns.Add("PropertyItem", Type.GetType("System.String"));
            dtReturn.Columns.Add("PropertyValue", Type.GetType("System.String"));

            //Create WebRequest
            WebRequest request = WebRequest.Create(url);
            using (Stream responseStream = request.GetResponse().GetResponseStream())
            {
                if (responseStream != null)
                {
                    using (TextReader textReader = new StreamReader(responseStream))
                    {
                        XmlTextReader reader = new XmlTextReader(textReader);
                        postcode = postcode.Replace(" ", "");

                        string option1 = "";
                        string option2 = "";

                        while (reader.Read())
                        {

                            if (reader.Name.Equals("line_1"))
                            {
                                option1 = reader.ReadString();
                            }
                            if (reader.Name.Equals("udprn"))
                            {
                                option2 = reader.ReadString();
                            }
                            if (option1 != "" && option2 != "")
                            {
                                dtReturn.Rows.Add(new object[] { option1, option2 });
                                option1 = "";
                                option2 = "";
                            }
                        }
                        return dtReturn;
                    }
                }
                throw new Exception("ResponseStream is NULL");
            }
        }
        catch (WebException ex)
        {
            return null;
        }
    }
调试屏幕截图


好的。当您想要返回流时,您不能使用station从
返回,因为当您使用
退出
时,您调用
Dispose
方法并关闭流

首先,您必须更改
readXML
方法

public DataTable readXML(string postcode, string response, string accessCode)
 {
        //Create URL
        string url = $"http://pcls1.craftyclicks.co.uk/xml/rapidaddress?postcode={postcode}&response={response}&key={accessCode}";

        DataTable dataTableResult  = null;

        try
            //Create WebRequest
            WebRequest request = WebRequest.Create(url);
            using (Stream responseStream = request.GetResponse().GetResponseStream())
            {
                if (responseStream != null)
                {
                    using (TextReader textReader = new StreamReader(responseStream))
                    {
                        XmlTextReader reader = new XmlTextReader(textReader);
                        Debug.Assert(reader != null, "Reader is NULL");

                        dataTableResult = returnAddressList(postcode, response, reader)
                    }
                }
                throw new Exception("ResponseStream is NULL");
            }

           return dataTableResult;
        }
        catch (WebException ex)
        {
            return null;
        }
接下来,您必须更改
returnAddressList
方法的定义,以使用stream from参数,如下所示:

   public DataTable returnAddressList(string postcode, string accessCode, XmlTextReader reader)
并删除了调用
readXML
方法的行

  XmlTextReader reader = readXML(postcode, "data_formatted", accessCode); - delete this line

这不是很好的重构,但您可以看到该做什么以及问题出在哪里。

正如评论中的讨论所述

using (TextReader textReader = new StreamReader(responseStream))
                {
                    XmlTextReader reader = new XmlTextReader(textReader);
                    Debug.Assert(reader != null, "Reader is NULL");
                    return reader;
                }
您创建了一个TextReader对象,稍后将在XmlTextReader的构造函数中使用该对象。。。返回XmlTextReader后,当您退出using块时,您将处理并关闭textReader,因此出现无法从关闭的textReader读取的错误。问题在于架构

您应该尝试将while循环逻辑从已有的解析方法拉入using块,例如

using(TextReader textReader = new StreamReader(responseStream))
        {
            XmlTextReader reader = new XmlTextReader(textReader);

            while(reader.Read())
            {
                if(reader.Name.Equals("line_1"))
                {
                    option1 = reader.ReadString();
                }
                if(reader.Name.Equals("udprn"))
                {
                    option2 = reader.ReadString();
                }
                if(option1 != "" && option2 != "")
                {
                    dtReturn.Rows.Add(new object[] { option1, option2 });
                    option1 = "";
                    option2 = "";
                }
            }
        }

谢谢你的投票什么失败了?有任何异常抛出吗?@pijemcolu我实际上查看了堆栈跟踪,它的说法是无法从封闭的文本流中读取,如果是make,因为它在returnAddressList的catch try元素中。在这种情况下,您可能发现了错误。。。您不应该在using块中
返回读取器
。您可以尝试更改该方法以返回字符串,然后可以解析该字符串。Msdn声明:首次创建和初始化读取器时,没有可用信息。必须调用Read来读取第一个节点。此方法需要数据流中至少四个字节才能开始解析。如果返回的字节少于四个,并且流中没有更多的数据,则该方法将失败。如果流中有更多数据,该方法将阻止解析,直到收到第四个字节。好的,但是你的尖叫并没有真正的帮助,给我们一些更好的东西,比如林,问题是什么,出现了什么错误
using(TextReader textReader = new StreamReader(responseStream))
        {
            XmlTextReader reader = new XmlTextReader(textReader);

            while(reader.Read())
            {
                if(reader.Name.Equals("line_1"))
                {
                    option1 = reader.ReadString();
                }
                if(reader.Name.Equals("udprn"))
                {
                    option2 = reader.ReadString();
                }
                if(option1 != "" && option2 != "")
                {
                    dtReturn.Rows.Add(new object[] { option1, option2 });
                    option1 = "";
                    option2 = "";
                }
            }
        }