Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# XmlSerializer和xsi:反序列化_C#_Wcf_Xmlserializer - Fatal编程技术网

C# XmlSerializer和xsi:反序列化

C# XmlSerializer和xsi:反序列化,c#,wcf,xmlserializer,C#,Wcf,Xmlserializer,由于xsi:type=“p:OUTPUT-HEADER”属性,我很难尝试反序列化与WCF SOAP服务错误详细信息部分相对应的这段XML代码: <p:OUTPUT-HEADER xsi:type="p:OUTPUT-HEADER" xmlns:p="http://aaa.bbb.ccc/v2" xmlns:ns0="http://aaa.bbb.ccc/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <F

由于xsi:type=“p:OUTPUT-HEADER”属性,我很难尝试反序列化与WCF SOAP服务错误详细信息部分相对应的这段XML代码:

<p:OUTPUT-HEADER xsi:type="p:OUTPUT-HEADER" xmlns:p="http://aaa.bbb.ccc/v2" xmlns:ns0="http://aaa.bbb.ccc/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <FAULT>
    <p:COD-ERROR>2951</p:COD-ERROR>
    <p:COD-SEV>8</p:COD-SEV>
    <p:MSG-ERROR>Error message</p:MSG-ERROR>
  </FAULT>
  <CNL-OUT>xxx</CNL-OUT>
</p:OUTPUT-HEADER>
XmlSerializer:

XmlSerializer x = new XmlSerializer(typeof(OutputHeader));
调用反序列化方法时出现的错误:

“无法识别指定的类型:名称 ='OUTPUT-HEADER',命名空间='',位于。“

是否可以修饰类以正确地反序列化此XML?
非常感谢您的任何想法,谢谢

而不是
XmlSerializer
,似乎必须使用来反序列化此XML。此序列化程序是唯一的,因此您只需删除指定使用
XmlSerializer
的代码即可

按如下方式设计您的类型:

[DataContract(Namespace = "")]
public abstract class OutputHeaderBase
{
    [DataMember(Name = "FAULT", Order = 1)]
    public Fault FaultSection { get; set; }

    [DataMember(Name = "CNL-OUT", Order = 2)]
    public string ClnOut { get; set; }
}

[DataContract(Name = "OUTPUT-HEADER", Namespace = "http://aaa.bbb.ccc/v2")]
public class OutputHeader : OutputHeaderBase
{
}

[DataContract(Name = "FAULT", Namespace = "http://aaa.bbb.ccc/v2")]
public class Fault
{
    [DataMember(Name = "COD-ERROR", Order = 1)]
    public int CodigoError { get; set; }

    [DataMember(Name = "COD-SEV", Order = 2)]
    public int Severidad { get; set; }

    [DataMember(Name = "MSG-ERROR", Order = 3)]
    public string Mensaje { get; set; }
}
[XmlRoot(ElementName = "OUTPUT-HEADER", Namespace = "http://aaa.bbb.ccc/v2")]
[XmlInclude(typeof(OutputHeaderSubclass))] // Artificial subtype to trigger handling of the `xsi:type` attribute.
[XmlInclude(typeof(OutputHeader))]
public class OutputHeader
{
    [XmlElement(ElementName = "FAULT", Namespace = "")]
    public Fault FaultSection { get; set; }

    [XmlElement(ElementName = "CNL-OUT", Namespace = "")]
    public string ClnOut { get; set; }
}

[XmlRoot(ElementName = "OUTPUT-HEADER-SUBCLASS", Namespace = "http://aaa.bbb.ccc/v2")]
public class OutputHeaderSubclass : OutputHeader
{
}
然后将您的操作契约声明为返回(或接受)类型为
OutputHeader
不是
OutputHeaderBase
)的对象

最后,通过从服务和/或操作契约中删除来切换回数据契约序列化,您应该已经准备好了。有关切换的详细信息,请参阅

(另请注意,
Fault
的属性需要放在正确的命名空间中。)

为什么这样做

该属性是w3c标准属性,允许元素显式声明其类型。在序列化多态类型时,使用和属性传递实际的类型信息。然而,以下要素:

<p:OUTPUT-HEADER 
    xsi:type="p:OUTPUT-HEADER" 
    xmlns:p="http://aaa.bbb.ccc/v2" 
    xmlns:ns0="http://aaa.bbb.ccc/v2" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
</p:OUTPUT-HEADER>

然后反序列化到
outputhreader
可能会很好地工作。不幸的是,事实并非如此
XmlSerializer
为冗余属性引发异常,而不是处理它。相反地,
DataContractSerializer
没有,所以这是要使用的。

WCF自动序列化和反序列化通过网络发送的内容。是否有特定的原因需要手动执行此操作?我知道“自动”方式应该是使用FaultException.GetDetail,但是没有生成OutputHeader类,因为wsdl不包含任何与此相关的信息。因此,我的下一步是获取FaultException.getReaderAttailContents()流并尝试对其进行反序列化。还是我在这里遗漏了什么?谢谢令人印象深刻,解释和记录都很好。我使用XmlSerializer是因为我认为DataContractSerializer无法处理层次结构中的不同名称空间,但现在我明白了,我误解了XML。非常感谢dbc!
[XmlRoot(ElementName = "OUTPUT-HEADER", Namespace = "http://aaa.bbb.ccc/v2")]
[XmlInclude(typeof(OutputHeaderSubclass))] // Artificial subtype to trigger handling of the `xsi:type` attribute.
[XmlInclude(typeof(OutputHeader))]
public class OutputHeader
{
    [XmlElement(ElementName = "FAULT", Namespace = "")]
    public Fault FaultSection { get; set; }

    [XmlElement(ElementName = "CNL-OUT", Namespace = "")]
    public string ClnOut { get; set; }
}

[XmlRoot(ElementName = "OUTPUT-HEADER-SUBCLASS", Namespace = "http://aaa.bbb.ccc/v2")]
public class OutputHeaderSubclass : OutputHeader
{
}