HttpResponseMessage无法反序列化XML,但文件流很好

时间:2017-05-31 15:15:28

标签: c# xsd deserialization

我试图使用第三方网络服务。我制作了一条请求消息,将其发送到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\"?>

我相信这是导致反序列化失败的原因。有没有一个干净的解决方案,或者我在其他地方做错了什么?

1 个答案:

答案 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解析器,您的代码现在应该可以正常工作。当然,如果你删除保存到文件,你应该能够正确地阅读和解析响应的内容。