由于命名空间,反序列化 xml 失败

Failed deserializing xml due to namespaces

我有以下 xml 我想反序列化为 c# class:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.s1.com/info/" xmlns:types="http://www.s1.com/info/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <tns:SessionInfo>
      <SessionId xsi:type="xsd:string">string</SessionId>
    </tns:SessionInfo>
  </soap:Header>
  <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <tns:LoginResponse>
      <Result xsi:type="xsd:boolean">boolean</Result>
    </tns:LoginResponse>
  </soap:Body>
</soap:Envelope>

我正在使用以下 classes 来反序列化 xml:

        public class SessionId
        {

            [XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
            public string Type { get; set; }

            [XmlText]
            public string Text { get; set; }
        }

        [XmlRoot(ElementName = "SessionInfo", Namespace = "http://www.s1.com/info/")]
        public class SessionInfo
        {

            [XmlElement(ElementName = "SessionId")]
            public SessionId SessionId { get; set; }

            [XmlAttribute(AttributeName = "id", Namespace = "")]
            public string Id { get; set; }

            [XmlText]
            public string Text { get; set; }
        }

        [XmlRoot(ElementName = "Header", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
        public class Header
        {

            [XmlElement(ElementName = "SessionInfo", Namespace = "http://www.s1.com/info/")]
            public SessionInfo SessionInfo { get; set; }
        }


        [XmlRoot(ElementName = "Result", Namespace = "")]
        public class Result
        {

            [XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
            public string Type { get; set; }

            [XmlText]
            public string Text { get; set; }
        }

        [XmlRoot(ElementName = "LoginResponse", Namespace = "http://www.s1.com/info/")]
        public class LoginResponse
        {

            [XmlElement(ElementName = "Result")]
            public Result Result { get; set; }
        }

        [XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
        public class Body
        {

            [XmlElement(ElementName = "LoginResponse", Namespace = "http://www.s1.com/info/")]
            public LoginResponse LoginResponse { get; set; }

            [XmlAttribute(AttributeName = "encodingStyle", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
            public string EncodingStyle { get; set; }

            [XmlText]
            public string Text { get; set; }
        }

        [XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
        public class Envelope
        {

            [XmlElement(ElementName = "Header", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
            public Header Header { get; set; }

            [XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
            public Body Body { get; set; }

            [XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Xsi { get; set; }

            [XmlAttribute(AttributeName = "xsd", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Xsd { get; set; }

            [XmlAttribute(AttributeName = "soapenc", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Soapenc { get; set; }

            [XmlAttribute(AttributeName = "tns", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Tns { get; set; }

            [XmlAttribute(AttributeName = "types", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Types { get; set; }

            [XmlAttribute(AttributeName = "soap", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Soap { get; set; }

            [XmlText]
            public string Text { get; set; }
        }

问题是 SessionId 元素没有被反序列化,我假设是由于命名空间不匹配。我尝试使用空字符串作为命名空间,但这也不起作用,因为它在反序列化过程中无法被识别。

非常感谢任何对此问题的见解。谢谢!

首先,SessionId 的命名空间有误。它从父级继承,您需要通过将其设置为空字符串来明确指定它没有。

其次,xsi:type 有特殊含义,你不应该尝试反序列化它。它用于指示元素的内容类型 - 在本例中为 string - 并将由序列化程序使用。这意味着这是许多可接受的类型之一。定义它的最简单方法是使用 object.

将它们放在一起,这应该有效:

[XmlElement(ElementName = "SessionId", Namespace = "")]
public object SessionId { get; set; }

SessionId 应该包含一个 string 对象,其值为 string.

我还会注意到其他各种小事:

  • 您不应将所有命名空间绑定(例如 Xsd)指定为模型的一部分。这比此模型级别低,将由序列化程序处理。
  • 您只需要 XmlRoot 在根
  • 您不需要 XmlText 没有任何文本的属性
  • 您需要对上面进行类似的更改以反序列化 Result
  • ElementNameAttributeName 将默认为 属性 的名称,因此如果您想要
  • ,则不必指定它们

考虑到这一点,这个模型应该可行:

public class SessionInfo
{
    [XmlElement(Namespace = "")]
    public object SessionId { get; set; }
}

public class Header
{
    [XmlElement(Namespace = "http://www.s1.com/info/")]
    public SessionInfo SessionInfo { get; set; }
}

public class LoginResponse
{
    [XmlElement(Namespace = "")]
    public object Result { get; set; }
}

public class Body
{
    [XmlElement(Namespace = "http://www.s1.com/info/")]
    public LoginResponse LoginResponse { get; set; }

    [XmlAttribute("encodingStyle", Namespace = "http://schemas.xmlsoap.org/soap/envelope/", Form = XmlSchemaForm.Qualified)]
    public string EncodingStyle { get; set; }
}

[XmlRoot(Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
    [XmlElement]
    public Header Header { get; set; }

    [XmlElement]
    public Body Body { get; set; }
}

您可以看到一个工作演示 here。我对源 XML 做了一个更改 - 我将 Result 值从 boolean 更改为 true,否则你会得到一个异常,因为 boolean不是该类型的有效值。