为xml反序列化自动创建的C#类不起作用

时间:2015-12-03 13:18:06

标签: c# xml deserialization xml-namespaces

我正在努力为这个xml创建反序列化类:

<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:stn="urn:response">
    <SOAP-ENV:Body>
        <Response>
            <Records xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="stn:Record[1]">
                <item xsi:type="stn:Record">
                    <person xsi:type="xsd:string">John Johnos</person>
                    <address xsi:type="xsd:string">Some Street 1</address>
                    <age xsi:type="xsd:string">24</age>
                </item>
            </Records>
            <status xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="stn:status[1]">
                <item xsi:type="stn:status">
                    <status xsi:type="xsd:string">success</status>
                    <message xsi:type="xsd:string"/>
                </item>
            </status>
        </Response>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我尝试使用自动创建的代码(在VisualStudio 12中:编辑 - &gt;选择性粘贴 - >将XML粘贴为类):

/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://schemas.xmlsoap.org/soap/envelope/", IsNullable = false)]
public partial class Envelope
{

    private EnvelopeBody bodyField;

    private string encodingStyleField;

    /// <remarks/>
    public EnvelopeBody Body
    {
        get
        {
            return this.bodyField;
        }
        set
        {
            this.bodyField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
    public string encodingStyle
    {
        get
        {
            return this.encodingStyleField;
        }
        set
        {
            this.encodingStyleField = value;
        }
    }
}

/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public partial class EnvelopeBody
{

    private Response responseField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "")]
    public Response Response
    {
        get
        {
            return this.responseField;
        }
        set
        {
            this.responseField = value;
        }
    }
}

/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class Response
{

    private ResponseRecords recordsField;

    private ResponseStatus statusField;

    /// <remarks/>
    public ResponseRecords Records
    {
        get
        {
            return this.recordsField;
        }
        set
        {
            this.recordsField = value;
        }
    }

    /// <remarks/>
    public ResponseStatus status
    {
        get
        {
            return this.statusField;
        }
        set
        {
            this.statusField = value;
        }
    }
}

/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ResponseRecords
{

    private ResponseRecordsItem itemField;

    private string arrayTypeField;

    /// <remarks/>
    public ResponseRecordsItem item
    {
        get
        {
            return this.itemField;
        }
        set
        {
            this.itemField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://schemas.xmlsoap.org/soap/encoding/")]
    public string arrayType
    {
        get
        {
            return this.arrayTypeField;
        }
        set
        {
            this.arrayTypeField = value;
        }
    }
}

/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ResponseRecordsItem
{

    private string personField;

    private string addressField;

    private byte ageField;

    /// <remarks/>
    public string person
    {
        get
        {
            return this.personField;
        }
        set
        {
            this.personField = value;
        }
    }

    /// <remarks/>
    public string address
    {
        get
        {
            return this.addressField;
        }
        set
        {
            this.addressField = value;
        }
    }

    /// <remarks/>
    public byte age
    {
        get
        {
            return this.ageField;
        }
        set
        {
            this.ageField = value;
        }
    }
}

/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ResponseStatus
{

    private ResponseStatusItem itemField;

    private string arrayTypeField;

    /// <remarks/>
    public ResponseStatusItem item
    {
        get
        {
            return this.itemField;
        }
        set
        {
            this.itemField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://schemas.xmlsoap.org/soap/encoding/")]
    public string arrayType
    {
        get
        {
            return this.arrayTypeField;
        }
        set
        {
            this.arrayTypeField = value;
        }
    }
}

/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ResponseStatusItem
{

    private string statusField;

    private object messageField;

    /// <remarks/>
    public string status
    {
        get
        {
            return this.statusField;
        }
        set
        {
            this.statusField = value;
        }
    }

    /// <remarks/>
    public object message
    {
        get
        {
            return this.messageField;
        }
        set
        {
            this.messageField = value;
        }
    }
}

我试图在XMLSerializer的帮助下反序列化:

var serializer = new XmlSerializer(typeof(Envelope));
var reader = new StringReader(response);
var flResponse = (Envelope)serializer.Deserialize(reader);

我收到的错误消息:

Message=The specified type was not recognized: name='Array', namespace='http://schemas.xmlsoap.org/soap/encoding/', at <Records xmlns=''>.

你能帮我改一下这个xml的反序列化类吗?

3 个答案:

答案 0 :(得分:6)

我尝试了很多东西并最终弄明白了。您发布的Xml无效,因为xsi:type不能用于反序列化。

有效的XML应如下所示:

<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:stn="urn:response">
    <SOAP-ENV:Body>
        <Response>
            <Records>
                <item>
                    <person >John Johnos</person>
                    <address >Some Street 1</address>
                    <age >24</age>
                </item>
            </Records>
            <status>
                <item>
                    <status >success</status>
                    <message/>
                </item>
            </status>
        </Response>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

代码应如下所示:

XDocument xml = XDocument.Parse(xmlInput);

XmlSerializer serializer = new XmlSerializer(typeof(Response));

using (StringReader stream = new StringReader(items[0].ToString()))
{
    var output = (Response)serializer.Deserialize(stream);
}

Autogenerate类将来自:

<Response>
  <Records  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <item>
      <person>John Johnos</person>
      <address >Some Street 1</address>
      <age>24</age>
    </item>
  </Records>
  <status xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <item >
      <status >success</status>
      <message />
    </item>
  </status>
</Response>

希望这很清楚。不知道如何从Envelope中删除类型,这可能不是你想要的解决方案。

我用来从Envelope获取东西的方法是XDocument.Descendants(elemmentName),它返回该名称的元素或List元素,然后你可以填充对象。它的工作量更大,但我认为它比转换xml更适合反序列化。

答案 1 :(得分:5)

为什么不为整个架构生成序列化库?

  1. 从邮件中的URL下载XSD架构文件并将其保存在某处

    http://schemas.xmlsoap.org/soap/encoding/

  2. 打开Visual Studio命令提示符并输入以下命令

    xsd / classes SoapEncoding.xsd

  3. 输出将是一个标题为SoapEncoding.cs

  4. 的文件
  5. 将此文件导入项目并尝试再次反序列化该消息。
  6. 如果一切顺利,这一切都应该有效。

答案 2 :(得分:0)

System.Diagnostics.Process process = new System.Diagnostics.Process();
                System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
                startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                startInfo.FileName = @"C:\Windows\system32\cmd.exe";
                string anyCommand = "cd C:\\Users\\JR5053169\\Documents\\visual studio 2010\\Projects\\WindowsFormsApplication1\\WindowsFormsApplication1\\bin\\Debug xsd";
                //C:\\Users\\JR5053169\\Documents\\visual studio 2010\\Projects\\WindowsFormsApplication1\\WindowsFormsApplication1
                //C:\\Users\\JR5053169\\Documents\\visual studio 2010\\Projects\\WindowsFormsApplication1\\WindowsFormsApplication1\\bin\\Debug
                startInfo.Arguments = "/c " + anyCommand;
                process.StartInfo = startInfo;
                process.Start();
                string Command1 = "xsd MakePayment.xml";
                startInfo.Arguments = "/c " + Command1;
                process.StartInfo = startInfo;
                process.Start();
                string Command2 = "xsd /c MakePayment.xsd";
                startInfo.Arguments = "/c " + Command2;
                process.StartInfo = startInfo;
                process.Start();