我试图使用第三方网络服务。我制作了一条请求消息,将其发送到httpclient并接收httpResponseMessage。
以下是处理呼叫的方法的摘录。对于我的情况,xml = true。
HttpResponseMessage response = await HttpClientInstance.SendAsync(requestMessage);
if (response.IsSuccessStatusCode)
{
if (xml)
{
try
{
//This fails with "the data at the root level is invalid"
XmlMediaTypeFormatter xmlFormatter = new XmlMediaTypeFormatter { UseXmlSerializer = true };
var content = response.Content.ReadAsAsync<T>(new Collection<MediaTypeFormatter> { xmlFormatter });
return content.Result;
}
catch (Exception tempe)
{
var content = response.Content.ReadAsAsync<T>();
return content.Result;
}
}
else
{
var content = response.Content.ReadAsAsync<T>();
return content.Result;
}
}
else
{
_logWriter.LogProcessFault(operationContext, null, GetCurrentMethod(), $"An error occurred while calling the API. URI = {endpoint}. StatusCode = {response.StatusCode}", null);
throw new Exception(response.StatusCode.ToString());
}
运行此代码后,尝试反序列化流中的XML数据时会引发错误。它失败并出现错误&#34;根级别的数据无效&#34;。
我注释掉了XMLMediaTypeFormatter和response.Content.Read ...并将其替换为
var fileStream = File.Create("D:\\Extract\\test.txt");
await response.Content.CopyToAsync(fileStream);
fileStream.Close();
将有效的XML写入文件。
在即时窗口中,我运行了response.Content.ReadAsStringAsync(),返回的字符串值有额外的反斜杠转义内容。
例如,这就是生成的test.txt文件中的内容:
<?xml version="1.0" encoding="utf-8"?>
这是来自ReadAsStringAsync:
<?xml version=\"1.0\" encoding=\"utf-8\"?>
我相信这是导致反序列化失败的原因。有没有一个干净的解决方案,或者我在其他地方做错了什么?
答案 0 :(得分:0)
问题出在以下代码块
中 await response.Content.CopyToAsync(fileStream);
fileStream.Close();
//This fails with "the data at the root level is invalid"
XmlMediaTypeFormatter xmlFormatter = new XmlMediaTypeFormatter { UseXmlSerializer = true };
var content = response.Content.ReadAsAsync<T>(new Collection<MediaTypeFormatter> { xmlFormatter });
HTTP响应只能被使用一次。换句话说,响应不会被读入某个缓冲区,从中可以为多个读取提供服务。它直接从套接字读取它。因此,一旦阅读,就无法再次阅读。
在上面,您将响应复制到文件中。这会消耗响应,并且不再可以再次读取。因此,当您在分配给content
时尝试再次读取它时,它什么都不读,因此XML解析器(格式化程序中)抛出xml语法错误b / c它基本上会收到一个空字符串。
不确定为什么要保存到文件,但是一旦保存到文件,您只需读取文件并将其内容发送到xml解析器,您的代码现在应该可以正常工作。当然,如果你删除保存到文件,你应该能够正确地阅读和解析响应的内容。