gpt4 book ai didi

c# - 反序列化 SOAP 消息的详细信息

转载 作者:太空狗 更新时间:2023-10-30 00:54:26 27 4
gpt4 key购买 nike

我正在开发 Windows 应用商店应用程序。

我有以下手动创建的故障类:

[XmlRoot(Namespace = "http://schemas.xmlsoap.org/soap/envelope/", ElementName = "Fault")]
public partial class SoapFault
{
[XmlElement(Form = XmlSchemaForm.Unqualified, ElementName = "faultcode")]
public String FaultCode { get; set; }

[XmlElement(Form = XmlSchemaForm.Unqualified, ElementName = "faultstring")]
public String FaultDescription { get; set; }

[XmlElement(Form = XmlSchemaForm.Unqualified, ElementName = "detail")]
public InnerException[] Detail { get; set; }
}

[XmlType(Namespace = "http://my.namespace.com", TypeName = "InnerException")]
public partial class InnerException
{
[XmlElement(Form = XmlSchemaForm.Unqualified, ElementName = "message")]
public String Message { get; set; }
}

这是我正在尝试读取的服务器的回复:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><env:Body><env:Fault><faultcode>env:Server</faultcode><faultstring>internal error</faultstring><detail><ns2:InnerException xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://ns1.my.namespace.com" xmlns:ns2="http://my.namespace.com" xmlns:ns3="http://ns3.my.namespace.com"><message>internal error</message></ns2:InnerException ></detail></env:Fault></env:Body></env:Envelope>

我尝试阅读它的方式如下:

using (XmlReader reader = XmlReader.Create(await response.Content.ReadAsStreamAsync()))
{
string SoapNamespace = "http://schemas.xmlsoap.org/soap/envelope/";
try
{
var serializer = new XmlSerializer(typeof(SoapFault));

reader.ReadStartElement("Envelope", SoapNamespace);
reader.ReadStartElement("Body", SoapNamespace);

var fault = serializer.Deserialize(reader) as SoapFault;

reader.ReadEndElement();
reader.ReadEndElement();
}
catch(Exception ex)
{
throw new Exception("Exception was thrown:" + ex.Message);
}
}

我已经尝试添加 namespace 、更改 XmlElement 属性,但我总是以 SoapFault 中的 Detail 属性为 NULL 告终。当我将类型更改为对象时,我至少得到一个包含数据的 XmlNode 集。

我必须在此代码中更改什么才能在序列化时实例化正确的类?

请注意:不幸的是,我不得不手动创建调用,无法使用自动生成的代码。

最佳答案

深受 How to Deserialize XML document 启发,我认为这应该可以解决问题。

我生成的类如下:

  1. 将 Xml 服务器回复保存到磁盘 (c:\temp\reply.xml)
  2. xsd c:\temp\reply.xml/o:"c:\temp"
  3. xsd c:\temp\reply.xsd reply_app1.xsd/classes/o:"c:\temp"
  4. 将 reply_app1.cs 添加到您的项目。

这导致:

//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.269
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System.Xml.Serialization;

//
// This source code was auto-generated by xsd, Version=4.0.30319.1.
//

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[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[] itemsField;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Body")]
public EnvelopeBody[] Items {
get {
return this.itemsField;
}
set {
this.itemsField = value;
}
}
}

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

private EnvelopeBodyFault[] faultField;

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

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
public partial class EnvelopeBodyFault {

private string faultcodeField;

private string faultstringField;

private EnvelopeBodyFaultDetail detailField;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string faultcode {
get {
return this.faultcodeField;
}
set {
this.faultcodeField = value;
}
}

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string faultstring {
get {
return this.faultstringField;
}
set {
this.faultstringField = value;
}
}

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public EnvelopeBodyFaultDetail detail {
get {
return this.detailField;
}
set {
this.detailField = value;
}
}
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
public partial class EnvelopeBodyFaultDetail {

private InnerException innerExceptionField;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Namespace="http://my.namespace.com")]
public InnerException InnerException {
get {
return this.innerExceptionField;
}
set {
this.innerExceptionField = value;
}
}
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://my.namespace.com")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://my.namespace.com", IsNullable=false)]
public partial class InnerException {

private string messageField;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string message {
get {
return this.messageField;
}
set {
this.messageField = value;
}
}
}

是的,它是自动生成的,但我认为这是创建可以反序列化的类的最简单方法。你可以这样做:

XmlDocument document = new XmlDocument();
document.Load(Server.MapPath("~/Data/reply.xml"));

System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(Envelope));
Envelope envelope = (Envelope)serializer.Deserialize(new StringReader(document.OuterXml));

它正确地获取了 Detail 属性。在您的情况下,您需要像以前一样使用 XmlReader 而不是我的 new StringReader(document.OuterXml),并将其包装在 using block 中,等等。

请记住,反序列化对象的某些属性名称与您在 SoapFault 类中的名称不完全匹配(它现在称为 Envelope,例如),并且一些属性表示为数组而不是单个对象,但如果需要,您可以调整 Xsd 以适应。

关于c# - 反序列化 SOAP 消息的详细信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12855488/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com