【发布时间】:2017-12-03 11:22:25
【问题描述】:
这个问题可能会重复,但我正在调用如下服务:
HttpClient httpClinet = new HttpClient();
httpClinet.DefaultRequestHeaders.Accept.Clear();
httpClinet.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
var str = "XrayService.asmx/GetOrdData?" + string.Format("ordId={0}&code={1}", range.ordId, range.code);
HttpResponseMessage response;
httpClinet.BaseAddress = new Uri("http://172.16.203.27:6043/");
response = httpClinet.GetAsync(str).Result;
if (response.IsSuccessStatusCode)
var caseInfos = response.Content.ReadAsAsync<IEnumerable<PI>>().Result;//Here is exception
一切正常,但是当我想运行 ReadAsAsync 时,出现如下异常:
错误:System.AggregateException:发生一个或多个错误。 ---> System.AggregateException:发生一个或多个错误。 ---> System.Runtime.Serialization.SerializationException:第 1 行位置 5 出错。需要命名空间“http://schemas.datacontract.org/2004/07/SATA_DTOs”中的元素“ArrayOfPI”。遇到名称为“PI”、命名空间“”的“元素”。 在 System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader,布尔值 verifyObjectName,DataContractResolver dataContractResolver) 在 System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator 读取器,布尔值 verifyObjectName,DataContractResolver dataContractResolver) 在 System.Runtime.Serialization.DataContractSerializer.ReadObject(XmlReader 阅读器) 在 System.Net.Http.Formatting.XmlMediaTypeFormatter.ReadFromStream(类型类型,流 readStream,HttpContent 内容,IFormatterLogger formatterLogger) 在 System.Net.Http.Formatting.XmlMediaTypeFormatter.ReadFromStreamAsync(类型类型,流 readStream,HttpContent 内容,IFormatterLogger formatterLogger) --- 从之前抛出异常的位置结束堆栈跟踪 ---
我正在通过Google Advanced Rest Client 测试该服务,结果如下:
状态:200 正常
响应标头:
cache-control: private, max-age=0
content-length: 360
content-type: text/xml; charset=utf-8
server:Microsoft-IIS/8.5
x-aspnet-version:4.0.30319
x-powered-by: ASP.NET
date: Sun, 03 Dec 2017 08:37:21 GMT
和输出:
<?xml version="1.0" encoding="utf-8" ?>
<PI>
<ordId>950177248</ordId>
<fnm>بهسا</fnm>
<lnm>حسنی</lnm>
<fthNm>علی</fthNm>
<pId>p2535154</pId>
<sex>F</sex>
<brthD>2003-02-05</brthD>
<addrs />
<nId>0025351540</nId>
<srvNm>|دندان بصورت پانورک</srvNm>
<rfrPhy>مهرزاد اميري-41853</rfrPhy>
</PI>
我还像这样装饰了 DTO:
namespace SATA_DTOs
{
[DataContract(Name = "PI")]
public class PI
{
[DataMember] public string ordId { get; set; }
[DataMember] public string fnm { get; set; }
[DataMember] public string lnm { get; set; }
[DataMember] public string fthNm { get; set; }
[DataMember] public string pId { get; set; }
[DataMember] public string sex { get; set; }
[DataMember] public string brthD { get; set; }
[DataMember] public string addrs { get; set; }
[DataMember] public string nId { get; set; }
[DataMember] public string srvNm { get; set; }
[DataMember] public string rfrPhy { get; set; }
}
}
更新:
就像另一次尝试一样,我想在这里得到结果 JSON 或 XML 但这也没有什么区别:
List<PI> model = null;
var client = new HttpClient();
var task = client.GetAsync(httpClinet.BaseAddress.ToString() + str)
.ContinueWith((taskwithresponse) =>
{
var response1 = taskwithresponse.Result;
var jsonString = response1.Content.ReadAsStringAsync();
m_Logging.Log(SharedLib.LoggingMode.Prompt, "JSON string created {0}...", jsonString);
jsonString.Wait();
model = Newtonsoft.Json.JsonConvert.DeserializeObject<List<PI>>(jsonString.Result);
});
task.Wait();
【问题讨论】:
-
尝试将 DataContractName 更改为“ArrayOfPI”。此外,请勿使用
.Result阻止 aysnc 呼叫。如果您不能正确异步,请使用同步 API,而不是 HttpClient。 -
在这种特殊情况下,您必须读取为字符串,然后加载 xml,检查第一个节点以确定结果是单个对象还是集合,然后根据类型相应地反序列化 xml
-
@Crowcoder 我认为你调用
GetAsync(str).Result或Get(str)没有区别。 -
@Aria,除非这是一个控制台应用程序,否则会有很大的不同。最好的情况是浪费资源,最坏的情况是导致僵局。您应该
await异步调用或不进行异步调用。 -
@Aria 考虑到响应的动态特性,您需要先检查它,然后再尝试反序列化它。否则你将不得不进行防御性编码并将它们包装在 try/catch 中。
标签: c# .net serialization httpresponse