C# 应用程序数据的WebClient下载未将结果集返回到读卡器中
我在这段代码中遇到了一个主要问题,我正在尝试从基于xml的CraftyClick服务器下载一个地址列表,我正在使用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
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 = "";
}
}
}