【问题标题】:InvalidDataContractException ("Type cannot be serialized") error using WCF DataContract使用 WCF DataContract 时出现 InvalidDataContractException(“类型无法序列化”)错误
【发布时间】:2013-12-16 13:43:06
【问题描述】:

我需要在我的数据协定中传递System.Net.NetworkInformation.PhysicalAddress(.NET Framework 内置类型)。由于这种类型不能自己序列化,我从它派生了我的助手类:

[DataContract]
public class PhysicalAddressSerializable : PhysicalAddress
{
    public PhysicalAddressSerializable()
        : base(new byte[] {0,0,0,0,0,0})
    { }
    public PhysicalAddressSerializable(byte[] address) 
        : base(address)
    { }

    [DataMember]
    public string AddressString { get { return ToString(); } set { Parse(value); } }
}

完美地序列化为 XML;但是,当我尝试将其传递给服务调用时,我得到 System.Runtime.Serialization.InvalidDataContractException:

无法序列化类型“System.Net.NetworkInformation.PhysicalAddress”。考虑使用 DataContractAttribute 属性对其进行标记,并使用 DataMemberAttribute 属性标记您想要序列化的所有成员。如果该类型是一个集合,请考虑使用 CollectionDataContractAttribute 对其进行标记。有关其他支持的类型,请参阅 Microsoft .NET Framework 文档。

堆栈跟踪:

Server stack trace: 
   at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(String message, Type type)
   at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(Int32 id, RuntimeTypeHandle typeHandle, Type type)
   at System.Runtime.Serialization.DataContract.GetDataContract(Int32 id, RuntimeTypeHandle typeHandle, SerializationMode mode)
   at System.Runtime.Serialization.ClassDataContract.ClassDataContractCriticalHelper..ctor(Type type)
   at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(Int32 id, RuntimeTypeHandle typeHandle, Type type)
   at System.Runtime.Serialization.DataContract.GetDataContract(Int32 id, RuntimeTypeHandle typeHandle, SerializationMode mode)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerializeReference(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
   at WriteUnitInfoToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , ClassDataContract )
   at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
   at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
   at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
   at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
   at System.Runtime.Serialization.XmlObjectSerializer.WriteObject(XmlDictionaryWriter writer, Object graph)
   at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameterPart(XmlDictionaryWriter writer, PartInfo part, Object graph)
   at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameter(XmlDictionaryWriter writer, PartInfo part, Object graph)
   at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameters(XmlDictionaryWriter writer, PartInfo[] parts, Object[] parameters)
   at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, String action, MessageDescription messageDescription, Object returnValue, Object[] parameters, Boolean isRequest)
   at System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage.OperationFormatterBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.Message.OnWriteMessage(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.BufferedMessageWriter.WriteMessage(Message message, BufferManager bufferManager, Int32 initialOffset, Int32 maxSizeQuota)
   at System.ServiceModel.Channels.BinaryMessageEncoderFactory.BinaryMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset)
   at System.ServiceModel.Channels.FramingDuplexSessionChannel.EncodeMessage(Message message)
   at System.ServiceModel.Channels.FramingDuplexSessionChannel.OnSendCore(Message message, TimeSpan timeout)
   at System.ServiceModel.Channels.TransportDuplexSessionChannel.OnSend(Message message, TimeSpan timeout)
   at System.ServiceModel.Channels.OutputChannel.Send(Message message, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)

【问题讨论】:

  • PhysicalAddress 长什么样子?
  • 这是一个框架类:msdn.microsoft.com/en-us/library/…,很抱歉没有把它说清楚! IE。我无法访问它,这就是为什么我必须首先重载它。
  • 在这种情况下,我强烈建议您使用 DTO 而不是 任何与 PhysicalAddress 相关的东西
  • 看起来这是要走的路。虽然,我仍然不明白为什么 wcf 序列化程序甚至关心基类,它没有自己的公共实例属性。
  • 好吧,序列化程序的工作是重建您发送的数据; 大多数 序列化器关心子类——尽管如果它们给你选择就好了。有时他们不会。

标签: c# wcf serialization .net-4.0 datacontract


【解决方案1】:

根据错误消息,它对基类 PhysicalAddress 不满意。所以要么:

  • 不要使用基类 - 使用不需要它的简单 DTO,或者:
  • 标记要序列化的基类

具体来说,类似:

[DataContract, KnownType(PhysicalAddressSerializable)]
public class PhysicalAddress {
    [DataMember(...)]
    public SomeType Foo {get;set;} // whatever
}

但是!从名称PhysicalAddressSerializable 看来,您不希望 将基类作为可序列化的。您可以尝试使用:

[XmlSerializerFormat]
public class PhysicalAddressSerializable : PhysicalAddress {...}

【讨论】:

  • +1 不过我觉得应该是... KnownType(typeof(PhysicalAddressSerializable)
  • 问题是,基类(System.Net.NetworkInformation.PhysicalAddress)是一个框架类(msdn.microsoft.com/en-us/library/…)。当我提供完全可序列化的派生类时,为什么序列化程序甚至会关心基类(甚至没有要序列化的公共字段/属性)?
  • 关于使用[XmlSerializerFormat] - 我试过了,同样的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多