XML反序列化无法解析属性类型

时间:2016-05-24 09:06:48

标签: c# xml xml-serialization asp.net-web-api2 xml-deserialization

我正在开发一个项目,我通过REST和Comet语义与API服务进行通信。

XML

所以,手头的问题。 当我尝试反序列化以下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#Class

我正在使用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时,我得到了不同的响应,有些验证了XML的正常性,而有些则不然。

对我而言,我发现很难理解结构应该如何运作。 似乎type属性应该基于xsi1属性构建,但我尝试过的所有内容都失败了。

我的最后一招是将响应作为字符串读取,然后剥离恼人的XML,以便可以正确地反序列化。

祝你好运。 一个有点沮丧的开发人员迫切需要帮助。

1 个答案:

答案 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)。