WCF抽象基类,在服务响应中不包含用于反序列化的抽象类型的复杂集合

Vul*_*ary 7 c# wcf wcf-binding

我们在我们的应用程序中使用了所有Response DTO的基类.该课程有以下签名:

[Serializable]
public abstract class ResponseBase
{
    public bool Successful { get; set; }
    public List<ResponseMessage> Messages { get; set; }

    //...Other code...
}
Run Code Online (Sandbox Code Playgroud)

Messages集合可以是以下任何类型:

[Serializable]
[XmlInclude(typeof(DebugMessage))]
[XmlInclude(typeof(InfoMessage))]
[XmlInclude(typeof(ValidationMessage))]
[XmlInclude(typeof(WarnMessage))]
[XmlInclude(typeof(RecoverableFaultMessage))]
[XmlInclude(typeof(FatalFaultMessage))]
public abstract class ResponseMessage
{
    //..Other code...
}
Run Code Online (Sandbox Code Playgroud)

具体版本:

[Serializable]
public class DebugMessage : ResponseMessage
{
    public override MessageType MessageType { get { return MessageType.Debug; } }
}
[Serializable]
public class InfoMessage : ResponseMessage
{
    public override MessageType MessageType { get { return MessageType.Info; } }
}
[Serializable]
public class ValidationMessage : ResponseMessage
{
    public override MessageType MessageType { get { return MessageType.Validation; } }
}
[Serializable]
public class WarnMessage : ResponseMessage
{
    public override MessageType MessageType { get { return MessageType.Warn; } }
}
[Serializable]
public class RecoverableFaultMessage : ResponseMessage
{
    public override MessageType MessageType { get { return MessageType.RecoverableFault; } }
}
[Serializable]
public class FatalFaultMessage : ResponseMessage
{
    public override MessageType MessageType { get { return MessageType.FatalFault; } }
}
Run Code Online (Sandbox Code Playgroud)

所有DTO Response对象都从ResponseBase继承,但即使在WCF契约中使用以下ServiceKnownTypes也是如此

[ServiceKnownType(typeof(ResponseBase))]
[ServiceKnownType(typeof(ResponseMessage))]
[ServiceKnownType(typeof(List<ResponseMessage>))]
[ServiceKnownType(typeof(DebugMessage))]
[ServiceKnownType(typeof(InfoMessage))]
[ServiceKnownType(typeof(ValidationMessage))]
[ServiceKnownType(typeof(WarnMessage))]
[ServiceKnownType(typeof(RecoverableFaultMessage))]
[ServiceKnownType(typeof(FatalFaultMessage))]
[ServiceKnownType(typeof(List<DebugMessage>))]
[ServiceKnownType(typeof(List<InfoMessage>))]
[ServiceKnownType(typeof(List<ValidationMessage>))]
[ServiceKnownType(typeof(List<WarnMessage>))]
[ServiceKnownType(typeof(List<RecoverableFaultMessage>))]
[ServiceKnownType(typeof(List<FatalFaultMessage>))]
Run Code Online (Sandbox Code Playgroud)

当我们将Message加载到ResponseBase Messages集合时,会抛出以下异常:

第1行位置错误906.元素'http://schemas.datacontract.org/2004/07/CX.Framework.Common.BaseTypes:ResponseMessage'包含映射到名称'http:// schemas的类型的数据. datacontract.org/2004/07/CX.Framework.Common.BaseTypes:WarnMessage".反序列化器不知道映射到此名称的任何类型.考虑使用DataContractResolver或将与"WarnMessage"对应的类型添加到已知类型列表中 - 例如,通过使用KnownTypeAttribute属性或将其添加到传递给DataContractSerializer的已知类型列表中.

我们已经在派生类型上完成了从ServiceKnownType到XMLInclude的所有操作.我对如何解决这个问题感到有点失落,并感谢任何人都可以提供的帮助.

Eug*_*sky 5

一些东西:

1)[XmlInclude]对它没有影响DataContractSerializer,它只用于XmlSerializer.

2)正如评论者"flem"建议的那样,我会[KnownType]直接使用ResponseMessage而不是[ServiceKnownType]服务.

3)我不记得DataContractSerializer偶数是否[KnownType][Serializable]类型上寻找.至少目前为了测试目的,如果上面的#2没有帮助,请尝试[DataContract]改为使用类型(并使用数据成员属性[DataMember]).