我是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;
}
}