应用程序数据的 WebClient 下载未将结果集返回到 reader
WebClient download of application data not returning result set into reader
我在使用这段代码时遇到了一个主要问题 我正在尝试简单地从基于 xml 的 craftycllick 服务器下载地址列表 我正在使用 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>
以及我用来解析的例程。
public DataTable returnAddressList(string postcode, string accessCode)
{
try
{
DataTable dtReturn = new DataTable();
dtReturn.Columns.Add("PropertyItem", Type.GetType("System.String"));
dtReturn.Columns.Add("PropertyValue", Type.GetType("System.String"));
postcode = postcode.Replace(" ", "");
XmlTextReader reader = readXML(postcode, "data_formatted", accessCode);
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;
}
catch (Exception ex)
{
return null;
}
}
我对上述函数的调用代码是
fhsBl.Helpers.CraftyPostCodeLookup _postCodeLookup = new fhsBl.Helpers.CraftyPostCodeLookup();
DataTable dt = new DataTable();
dt = _postCodeLookup.returnAddressList("AA11AA", "API KEY DONT BE NOSY");
编辑 1
好的,建议我更改我的代码以使用 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;
}
}
调试的屏幕截图
好的。当您想要 return 流时,您不能从 using statment
return,因为当您从 using
退出时,您调用 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
方法的定义以使用来自参数的流,如下所示:
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 的构造函数中使用该对象 reader ... 在您 return XmlTextReader 之后,当您退出使用块时,您将处理并关闭 textReader ,因此出现无法从关闭的 textReader 中读取的错误。问题出在我的架构上。
您应该尝试将 while 循环逻辑从您拥有的 Parse 方法中提取到 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 = "";
}
}
}
我在使用这段代码时遇到了一个主要问题 我正在尝试简单地从基于 xml 的 craftycllick 服务器下载地址列表 我正在使用 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>
以及我用来解析的例程。
public DataTable returnAddressList(string postcode, string accessCode)
{
try
{
DataTable dtReturn = new DataTable();
dtReturn.Columns.Add("PropertyItem", Type.GetType("System.String"));
dtReturn.Columns.Add("PropertyValue", Type.GetType("System.String"));
postcode = postcode.Replace(" ", "");
XmlTextReader reader = readXML(postcode, "data_formatted", accessCode);
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;
}
catch (Exception ex)
{
return null;
}
}
我对上述函数的调用代码是
fhsBl.Helpers.CraftyPostCodeLookup _postCodeLookup = new fhsBl.Helpers.CraftyPostCodeLookup();
DataTable dt = new DataTable();
dt = _postCodeLookup.returnAddressList("AA11AA", "API KEY DONT BE NOSY");
编辑 1 好的,建议我更改我的代码以使用 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;
}
}
调试的屏幕截图
好的。当您想要 return 流时,您不能从 using statment
return,因为当您从 using
退出时,您调用 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
方法的定义以使用来自参数的流,如下所示:
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 的构造函数中使用该对象 reader ... 在您 return XmlTextReader 之后,当您退出使用块时,您将处理并关闭 textReader ,因此出现无法从关闭的 textReader 中读取的错误。问题出在我的架构上。
您应该尝试将 while 循环逻辑从您拥有的 Parse 方法中提取到 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 = "";
}
}
}