C# 将SOAP XML反序列化为对象时出现异常

C# 将SOAP XML反序列化为对象时出现异常,c#,xml,wcf,soap,xml-deserialization,C#,Xml,Wcf,Soap,Xml Deserialization,我正在开发一个WCF服务,它可以接受和返回SOAP1.1消息。但是,将SOAP主体反序列化到对象时遇到问题。现在我有 namespace MyAPI { [ServiceContract] public interface IMyService { [OperationContract(IsOneWay = false, Action = "*", ReplyAction = "*")] [WebInvoke(Method

我正在开发一个WCF服务,它可以接受和返回SOAP1.1消息。但是,将SOAP主体反序列化到对象时遇到问题。现在我有

namespace MyAPI
{    
    [ServiceContract]
    public interface IMyService
    {
        [OperationContract(IsOneWay = false, Action = "*", ReplyAction = "*")]     
        [WebInvoke(Method = "POST",           
           BodyStyle = WebMessageBodyStyle.Bare, RequestFormat=WebMessageFormat.Xml)]
        Message ProcessMessgae(Message message);       
    }
}

public class MyService : IMyService
{  
    public Message ProcessMessgae(Message message)
    {
        MessageBuffer buffer = message.CreateBufferedCopy(8192);

        // Get a copy of the original message.
        Message msgCopy = buffer.CreateMessage();

        // Take another copy of the same message. 
        Message returnMsg = buffer.CreateMessage();

        // Use the msgCopy to get an XML and extract the body contents. Once this message has been read and consumed,

        System.Xml.XmlDictionaryReader xrdr = msgCopy.GetReaderAtBodyContents();

        string bodyData = xrdr.ReadOuterXml();

        var reader = new StringReader(bodyData);
        var serializer = new XmlSerializer(typeof(OTA_HotelAvailRQ));
        var instance = (OTA_HotelAvailRQ)serializer.Deserialize(reader);

        return returnMsg; 
    }
}
这是我自动生成的对象

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.2046.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.opentravel.org/OTA/2003/05")]
public partial class OTA_HotelAvailRQ : object, System.ComponentModel.INotifyPropertyChanged
{

    private string echoTokenField;

    private System.DateTime timeStampField;

    private bool timeStampFieldSpecified;

    private bool targetFieldSpecified;

    private decimal versionField;

    private bool availRatesOnlyField;

    private bool availRatesOnlyFieldSpecified;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string EchoToken
    {
        get
        {
            return this.echoTokenField;
        }
        set
        {
            this.echoTokenField = value;
            this.RaisePropertyChanged("EchoToken");
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public System.DateTime TimeStamp
    {
        get
        {
            return this.timeStampField;
        }
        set
        {
            this.timeStampField = value;
            this.RaisePropertyChanged("TimeStamp");
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool TimeStampSpecified
    {
        get
        {
            return this.timeStampFieldSpecified;
        }
        set
        {
            this.timeStampFieldSpecified = value;
            this.RaisePropertyChanged("TimeStampSpecified");
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public decimal Version
    {
        get
        {
            return this.versionField;
        }
        set
        {
            this.versionField = value;
            this.RaisePropertyChanged("Version");
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public bool AvailRatesOnly
    {
        get
        {
            return this.availRatesOnlyField;
        }
        set
        {
            this.availRatesOnlyField = value;
            this.RaisePropertyChanged("AvailRatesOnly");
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool AvailRatesOnlySpecified
    {
        get
        {
            return this.availRatesOnlyFieldSpecified;
        }
        set
        {
            this.availRatesOnlyFieldSpecified = value;
            this.RaisePropertyChanged("AvailRatesOnlySpecified");
        }
    }

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string propertyName)
    {
        System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
        if ((propertyChanged != null))
        {
            propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
    }
}
//
[System.CodeDom.Compiler.GeneratedCodeAttribute(“System.Xml”,“4.7.2046.0”)]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute(“代码”)]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true,命名空间=”http://www.opentravel.org/OTA/2003/05")]
公共部分类OTA_HotelAvailerQ:对象,System.ComponentModel.INotifyPropertyChanged
{
私有字符串字段;
private System.DateTime时间戳字段;
指定的专用布尔值;
指定的专用布尔目标域;
私有十进制版本字段;
私人bool可用的最新字段;
仅指定了专用布尔值字段;
/// 
[System.Xml.Serialization.XmlAttributeAttribute()]
公共字符串EchoToken
{
得到
{
返回此.echotoken字段;
}
设置
{
this.echoTokenField=值;
此.RaisePropertyChanged(“EchoToken”);
}
}
/// 
[System.Xml.Serialization.XmlAttributeAttribute()]
public System.DateTime时间戳
{
得到
{
返回此.timestamp字段;
}
设置
{
this.timeStampField=值;
此.RaisePropertyChanged(“时间戳”);
}
}
/// 
[System.Xml.Serialization.XmlIgnoreAttribute()]
指定公共bool时间戳
{
得到
{
返回指定的这个.timestampfield;
}
设置
{
this.timeStampFieldSpecified=值;
此.RaisePropertyChanged(“指定时间”);
}
}
/// 
[System.Xml.Serialization.XmlAttributeAttribute()]
公开十进制版本
{
得到
{
返回此.version字段;
}
设置
{
this.versionField=值;
本.RaisePropertyChanged(“版本”);
}
}
/// 
[System.Xml.Serialization.XmlAttributeAttribute()]
公共图书馆
{
得到
{
返回此.availRatesOnlyField;
}
设置
{
this.availRatesOnlyField=值;
本.RaiseProperty已更改(“可用”);
}
}
/// 
[System.Xml.Serialization.XmlIgnoreAttribute()]
公共布尔值仅指定
{
得到
{
返回此.availRatesOnlyFieldSpecified;
}
设置
{
this.availRatesOnlyFieldSpecified=值;
此.raiseProperty已更改(“指定可用日期”);
}
}
公共事件System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
受保护的void RaisePropertyChanged(字符串propertyName)
{
System.ComponentModel.PropertyChangedEventHandler propertyChanged=this.propertyChanged;
如果((propertyChanged!=null))
{
propertyChanged(这是新的System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
然而,当我运行代码时,我在下面一行得到一个异常
var instance=(OTA_HotelAvailRQ)serializer.Deserialize(reader)

我发布的soapxml是


测试
最好的


实际的例外是

如果将名称空间添加到xmlserializer,会发生什么

var instance = (OTA_HotelAvailRQ)serializer.Deserialize(reader, "http://www.opentravel.org/OTA/2003/05");
另一个选项是执行如下操作,您可能需要ReadOuterXml()而不是ReadInnerXml,命名空间也可以从此方法中删除:

System.Xml.Linq.XElement body = System.Xml.Linq.XElement.Parse(msgCopy.GetReaderAtBodyContents().ReadInnerXml());
var instance = Deserialize<OTA_HotelAvailRQ>(body, "http://www.opentravel.org/OTA/2003/05");

public static T Deserialize<T>(XElement xElement, string nameSpace)
{
    using (MemoryStream memoryStream = new MemoryStream(Encoding.ASCII.GetBytes(xElement.ToString())))
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T), nameSpace);
        return (T)xmlSerializer.Deserialize(memoryStream);
    }
}
System.Xml.Linq.XElement body=System.Xml.Linq.XElement.Parse(msgCopy.GetReaderAtBodyContents().ReadInnerXml());
var instance=反序列化(正文,“http://www.opentravel.org/OTA/2003/05");
公共静态T反序列化(XElement XElement,字符串命名空间)
{
使用(MemoryStream MemoryStream=new MemoryStream(Encoding.ASCII.GetBytes(xElement.ToString()))
{
XmlSerializer XmlSerializer=新的XmlSerializer(typeof(T),名称空间);
返回(T)xmlSerializer.Deserialize(memoryStream);
}
}

如果您仍然有问题,还有一种方法可以使用
DataContractSerializer
SoapreflectionImporter
,但是您没有一个非常复杂的对象,这可能是多余的。

使用
var instance=msgCopy.GetBody()
工作得更好吗?我按照您上面的建议进行了尝试,但没有成功{“应为命名空间“”中的元素‘OTA_HotelAvailRQ’……遇到命名空间“”中名为‘OTA_HotelAvailRQ’的‘元素’。”}添加var实例=(OTA_HotelAvailRQ)序列化程序。反序列化(读取器“”)不会编译。您的第二个建议有效,但正如您提到的,我必须使用ReadOuterXml()而不是ReadInnerXml()@Tommassiov我的错误是,没有编译的部分必须在实例化xmlserialer时将名称空间添加到构造函数中,而不是在反序列化方法上。很高兴第二个选项能起作用:)