WCF:不将数组中的knowntype反序列化为派生类,不确定如何调试datacontractserializer

时间:2013-07-31 14:21:45

标签: wcf inheritance deserialization datacontractserializer known-types

我是WCF的新手,希望有人能提供帮助。我有一个非抽象的基类,它使用派生类应用[knowntype],并且在数组中对我的服务的请求体中使用。当我使用带有派生类的XML调用服务时,反序列化后的所有代码都是基类,而不是派生类。

输入XML有一个xml实例类型(xsi:type)属性似乎完全被忽略 - 无论我设置它,系统只给我基类没有错误。

我得到的实际代码/等是巨大的。所以,我已经敲了一个有代表性的测试,但是这个工作正常,有趣的是,如果我将xsi:type更改为无效类型,我会从DataContractSerializer获得异常,与代码I不同想工作!

如果我更改元素的名称以强制例外,我会看到提到DataContractSerializer

`Start element 'itemz' does not match end element 'item'. Line 110, position 23.
at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String     res, String arg1, String arg2, String arg3)
   at System.Xml.XmlUTF8TextReader.ReadEndElement()
   at System.Xml.XmlUTF8TextReader.Read()
   at System.Xml.XmlBaseReader.Skip()
   at System.Runtime.Serialization.XmlReaderDelegator.Skip()
   at ReadArrayOfitemFromXml(XmlReaderDelegator , XmlObjectSerializerReadContext ,     XmlDictionaryString , XmlDictionaryString , CollectionDataContract )
   at    System.Runtime.Serialization.CollectionDataContract.ReadXmlValue(XmlReaderDelegator     xmlReader, XmlObjectSerializerReadContext context)
   at     System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDe    legator reader, String name, String ns, Type declaredType, DataContract&     dataContract)
   at    System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDe    legator xmlReader, Int32 id, RuntimeTypeHandle declaredTypeHandle, String name, String     ns)
   at ReadinteropSectionFromXml(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString[] , XmlDictionaryString[] )
...
at     System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, String name, String ns)
at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)`

所以,我有点难过:从异常情况来看,看起来它在两种情况下都使用DataContractSerializer,但在实际代码中,它甚至都没有尝试使用派生类型。与旧的ASMX样式服务不同,我还没有找到一种跳转到序列化程序代码的方法来查看它在做什么。我做错了什么,我该如何调试序列化器?

如果有任何帮助,我可以尝试提供更多代码/ xml。我得到的“演示”代码如下;就像真正的代码一样,它使用[MessageContract]作为服务,但实体都是对于hilt的DataContract(在真实代码中,SVCUTIL生成了具有相似属性的代理代码)。

[DataContract] public class Security
{
    [DataMember] public string Username { get; set; }
}

[DataContract] public class Wrapper
{
    [DataMember] public BaseEntity[] MyEntities { get; set; }
}

[DataContract, KnownType(typeof(AdvancedEntity))] public class BaseEntity
{
    [DataMember] public string Name { get; set; }
}

[DataContract] public class AdvancedEntity : BaseEntity
{
    [DataMember] public int Age { get; set; }
}

[ServiceContract] interface ITrivialService
{
    [OperationContract] Response DoStuff(Request request);
}

[MessageContract] public class Request
{
    [MessageHeader] public Security AuthenticationDetails { get; set; }

    [MessageBodyMember] public Wrapper MyWrapper { get; set; }
}

[MessageContract] public class Response
{
    [MessageBodyMember] public BaseEntity Entity { get; set; }
}

public class TrivialService : ITrivialService
{
    public Response DoStuff(Request request)
    {
        string newName = string.Empty;

        BaseEntity entity = request.MyWrapper.MyEntities[0];

        //do something different depending on which entity we got
        AdvancedEntity advancedEntity = entity as AdvancedEntity;
        if (advancedEntity != null)
        {
            advancedEntity.Name = request.AuthenticationDetails.Username;
            advancedEntity.Age++;
        }
        else
        {
            entity.Name = entity.Name + " and " + request.AuthenticationDetails.Username;
        }

        Response response = new Response();
        response.Entity = entity;

        return response;
    }
}

0 个答案:

没有答案