我正在开发一个项目,我通过REST和Comet语义与API服务进行通信。
所以,手头的问题。 当我尝试反序列化以下XML时收到此错误。
解析类型错误" xsi:SubscriptionEvent" NetBike.Xml.TypeResolvers.XmlTypeResolveException
注意:我使用NetBike,但错误也存在于默认的xml格式化程序中
<?xml version="1.0" encoding="UTF-8"?>
<xsi:Event
xsi1:type="xsi:SubscriptionEvent"
xmlns:xsi="http://schema.broadsoft.com/xsi"
xmlns:xsi1="http://www.w3.org/2001/XMLSchema-instance">
<xsi:eventID>0787e727-e73d-43e0-a7b1-e968ba72ea53</xsi:eventID>
<xsi:sequenceNumber>1</xsi:sequenceNumber>
<xsi:userId>11111111@voip.company.domain</xsi:userId>
<xsi:externalApplicationId>NewClient</xsi:externalApplicationId>
<xsi:subscriptionId>24def51b-21fb-4d60-a1ef-67477dcafcfb</xsi:subscriptionId>
<xsi:channelId>575cfe44-2cc7-4cf5-bc05-bcc462bcbb02</xsi:channelId>
<xsi:targetId>22222222@voip.company.domain</xsi:targetId>
<xsi:eventData xsi1:type="xsi:ACDSubscriptionEvent"/>
</xsi:Event>
我不是XML&#34; Jedi knight&#34;,但我知道基础知识。 错误告诉我我的类型xsi1有问题:type =&#34; xsi:SubscriptionEvent&#34;这是根xml(Event)元素的属性,这是有问题的三个属性。
xsi1:type="xsi:SubscriptionEvent"
xmlns:xsi="http://schema.broadsoft.com/xsi"
xmlns:xsi1="http://www.w3.org/2001/XMLSchema-instance"
我正在使用C#,直到现在我根据开发时返回给我的XML创建等效类没有任何问题。 如果我拿出坏数据&#34;避免例外。
事件类(我在Web API V2环境中使用它,所以从技术上讲它是一个模型)
[XmlRoot(ElementName = "Event", Namespace = "http://schema.broadsoft.com/xsi")]
public class Event
{
[XmlElement(ElementName = "eventID", Namespace = "http://schema.broadsoft.com/xsi")]
public string EventID { get; set; }
[XmlElement(ElementName = "sequenceNumber", Namespace = "http://schema.broadsoft.com/xsi")]
public string SequenceNumber { get; set; }
[XmlElement(ElementName = "userId", Namespace = "http://schema.broadsoft.com/xsi")]
public string UserId { get; set; }
[XmlElement(ElementName = "externalApplicationId", Namespace = "http://schema.broadsoft.com/xsi")]
public string ExternalApplicationId { get; set; }
[XmlElement(ElementName = "subscriptionId", Namespace = "http://schema.broadsoft.com/xsi")]
public string SubscriptionId { get; set; }
[XmlElement(ElementName = "channelId", Namespace = "http://schema.broadsoft.com/xsi")]
public string ChannelId { get; set; }
[XmlElement(ElementName = "targetId", Namespace = "http://schema.broadsoft.com/xsi")]
public string TargetId { get; set; }
[XmlElement(ElementName = "eventData", Namespace = "http://schema.broadsoft.com/xsi")]
public EventData eventData { get; set; }
[XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Type { get; set; }
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
public string xsi { get; set; }
[XmlAttribute(AttributeName = "xsi1", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Xsi1 { get; set; }
[XmlRoot(ElementName = "eventData", Namespace = "http://schema.broadsoft.com/xsi")]
public class EventData
{
[XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Type { get; set; }
}
}
此课程主要来自http://xmltocsharp.azurewebsites.net/ (这大大加快了这项本来很乏味的任务)
当我通过不同的XML验证器运行XML时,我得到了不同的响应,有些验证了XML的正常性,而有些则不然。
对我而言,我发现很难理解结构应该如何运作。 似乎type属性应该基于xsi1属性构建,但我尝试过的所有内容都失败了。
我的最后一招是将响应作为字符串读取,然后剥离恼人的XML,以便可以正确地反序列化。
祝你好运。 一个有点沮丧的开发人员迫切需要帮助。
答案 0 :(得分:1)
我认为引起了混淆,因为xsi:type
是XML模式的一部分,并定义了各种元素的类型。您尝试将其视为普通属性,并且序列化程序正在尝试使用它来确定要将数据映射到的对象。它所寻找的对象没有在模型中定义。
基本上,您需要在XML所暗示的类型层次结构之后对类进行建模。因此,您有一个基础Event
类,其中包含SubscriptionEvent
个子类,并且您的基类EventData
类具有ACDSubscriptionEvent
子类。
请注意(至少对于XmlSerializer
),您可以省略很多名称空间,因为它们是从父级继承的。您可能比我更了解层次结构,因此可以将一些属性移动到基类等中。理想情况下,您具有XML模式文件(.xsd)并且能够生成使用xsd.exe
的类,但这适用于给定的XML:
[XmlInclude(typeof(SubscriptionEvent))]
[XmlRoot(Namespace = "http://schema.broadsoft.com/xsi")]
public abstract class Event
{
}
[XmlType(Namespace = "http://schema.broadsoft.com/xsi")]
public class SubscriptionEvent : Event
{
[XmlElement(ElementName = "eventID")]
public string EventID { get; set; }
[XmlElement(ElementName = "sequenceNumber")]
public string SequenceNumber { get; set; }
[XmlElement(ElementName = "userId")]
public string UserId { get; set; }
[XmlElement(ElementName = "externalApplicationId")]
public string ExternalApplicationId { get; set; }
[XmlElement(ElementName = "subscriptionId")]
public string SubscriptionId { get; set; }
[XmlElement(ElementName = "channelId")]
public string ChannelId { get; set; }
[XmlElement(ElementName = "targetId")]
public string TargetId { get; set; }
[XmlElement(ElementName = "eventData")]
public EventData EventData { get; set; }
}
[XmlInclude(typeof(ACDSubscriptionEvent))]
public abstract class EventData
{
}
[XmlType(Namespace = "http://schema.broadsoft.com/xsi")]
public class ACDSubscriptionEvent : EventData
{
}
请参阅this fiddle了解工作演示(使用XmlSerializer
)。