我正在使用基于XML的API,因为它的根节点可以返回SuccessResponse
或ErrorResponse
。
我使用下面的方法反序列化数据,但我不知道如何处理返回不是SuccessResponse
的情况。
处理返回的XML不是预期格式的情况的最佳方法是什么?
我知道我可以采取黑客的方式,并寻找SuccessResponse
或ErrorResponse
的出现,但这感觉不对。
TheIconicApiResult result = this.apiService.SendGetRequest("GetProducts", new List<AbstractParam>() { new FilterParam("live"), new LimitParam(5000) });
IXmlSerialiser xmlSerialiser = new XmlSerialiser();
var xmlBody = xmlSerialiser.ParseXML<SuccessResponse>(result.ResponseBody);
public TObject ParseXML<TObject>(string xml)
{
using (TextReader reader = new StreamReader(GetMemoryStream(xml)))
{
XmlSerializer serialiser = new XmlSerializer(typeof(TObject));
return (TObject)serialiser.Deserialize(reader);
}
}
答案 0 :(得分:2)
如果您的XML流包含多种可能的文档类型之一,则可以为每种类型构造XmlSerializer
并调用XmlSerializer.CanDeserialize(XmlReader)
以连续测试是否可以将文档反序列化为该类型。此方法不会使XmlReader
超过根元素,因此可以多次调用它而无需重新读取流。
例如,您可以引入以下扩展方法:
public static partial class XmlSerializerExtensions
{
public static object DeserializePolymorphicXml(this string xml, params Type[] types)
{
using (var textReader = new StringReader(xml))
{
return textReader.DeserializePolymorphicXml(types);
}
}
public static object DeserializePolymorphicXml(this TextReader textReader, params Type[] types)
{
if (textReader == null || types == null)
throw new ArgumentNullException();
var settings = new XmlReaderSettings { CloseInput = false }; // Let caller close the input.
using (var xmlReader = XmlReader.Create(textReader, settings))
{
foreach (var type in types)
{
var serializer = new XmlSerializer(type);
if (serializer.CanDeserialize(xmlReader))
return serializer.Deserialize(xmlReader);
}
}
throw new XmlException("Invalid root type.");
}
}
然后按如下方式使用:
var xmlBody = result.ResponseBody.DeserializePolymorphicXml(typeof(SuccessResponse), typeof(FailResponse));
if (xmlBody is SuccessResponse)
{
// Handle successful response
}
else if (xmlBody is FailResponse)
{
// Handle failed response
}
else
{
// unknown response
throw new InvalidOperationException("unknown response");
}
示例fiddle。