none
FlowDocument 类型不能做为 DataContract 的 DataMember 来使用吗? RRS feed

  • 问题

  • 大家好,我在利用 WCF 通讯的时候在自定义数据契约中定义了 FlowDocument 类型的成员,但是在运行 WCF测试客户端时出现了错误,去掉该成员则没有问题,望高手明释。

    数据契约如下:

      [DataContract]
      public class Report 
      {
        [DataMember]
        public string Author { get; set; }
    
        [DataMember]
        public DateTime Date { get; set; }
    
        [DataMember]
        public FlowDocument Content { get; set; }
      }
    

    错误信息如下:

     错误: 无法从 net.tcp://localhost:4633/Service1/mex 获取元数据如果是您有权访问的 Windows (R) Communication Foundation 服务,请检查是否已启用在指定地址发布元数据。有关启用元数据发布的帮助,请参阅 http://go.microsoft.com/fwlink/?LinkId=65455 上的 MSDN 文档。WS-Metadata Exchange 错误    URI: net.tcp://localhost:4633/Service1/mex    元数据包含无法解析的引用:“net.tcp://localhost:4633/Service1/mex”。   

    <?xml version="1.0" encoding="utf-16"?>
    <Fault xmlns="http://www.w3.org/2003/05/soap-envelope">
     <Code>
      <Value>Receiver</Value>
      <Subcode>
       <Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</Value>
      </Subcode>
     </Code>
     <Reason>
      <Text xml:lang="zh-CN">在调用 WSDL 导出扩展过程中引发异常: System.ServiceModel.Description.DataContractSerializerOperationBehavior协定: http://tempuri.org/:IChatService</Text>
     </Reason>
     <Detail xmlns:s="http://www.w3.org/2003/05/soap-envelope">
      <ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
       <HelpLink i:nil="true"></HelpLink>
       <InnerException>
        <HelpLink i:nil="true"></HelpLink>
        <InnerException i:nil="true"></InnerException>
        <Message>无法序列化类型“System.Windows.Data.BindingExpressionBase”。可以考虑使用 DataContractAttribute 属性对其进行标记,以及使用 DataMemberAttribute 属性标记所有想要序列化的该类型的成员。有关其他支持的类型,请参阅 Microsoft .NET Framework 文档。</Message>
        <StackTrace>  在 System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(String message, Type type)  在 System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(Int32 id, RuntimeTypeHandle typeHandle, Type type)  在 System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(Int32 id, RuntimeTypeHandle typeHandle, Type type)  在 System.Runtime.Serialization.DataContract.GetDataContract(RuntimeTypeHandle typeHandle, Type type, SerializationMode mode)  在 System.Runtime.Serialization.DataContractSet.GetDataContract(Type clrType)  在 System.Runtime.Serialization.DataContractSet.GetItemTypeDataContract(CollectionDataContract collectionContract)  在 System.Runtime.Serialization.DataContractSet.AddCollectionDataContract(CollectionDataContract collectionDataContract)  在 System.Runtime.Serialization.DataContractSet.Add(XmlQualifiedName name, DataContract dataContract)  在 System.Runtime.Serialization.DataContractSet.AddClassDataContract(ClassDataContract classDataContract)  在 System.Runtime.Serialization.DataContractSet.Add(XmlQualifiedName name, DataContract dataContract)  在 System.Runtime.Serialization.DataContractSet.AddClassDataContract(ClassDataContract classDataContract)  在 System.Runtime.Serialization.DataContractSet.Add(XmlQualifiedName name, DataContract dataContract)  在 System.Runtime.Serialization.DataContractSet.AddClassDataContract(ClassDataContract classDataContract)  在 System.Runtime.Serialization.DataContractSet.Add(XmlQualifiedName name, DataContract dataContract)  在 System.Runtime.Serialization.DataContractSet.AddClassDataContract(ClassDataContract classDataContract)  在 System.Runtime.Serialization.DataContractSet.Add(XmlQualifiedName name, DataContract dataContract)  在 System.Runtime.Serialization.DataContractSet.Add(Type type)  在 System.Runtime.Serialization.XsdDataContractExporter.Export(Type type)  在 System.ServiceModel.Description.MessageContractExporter.ExportType(Type type, String partName, String operationName, XmlSchemaType&amp; xsdType)  在 System.ServiceModel.Description.DataContractSerializerMessageContractExporter.ExportBody(Int32 messageIndex, Object state)  在 System.ServiceModel.Description.MessageContractExporter.ExportMessage(Int32 messageIndex, Object state)  在 System.ServiceModel.Description.MessageContractExporter.ExportMessageContract()  在 System.ServiceModel.Description.DataContractSerializerOperationBehavior.System.ServiceModel.Description.IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext contractContext)  在 System.ServiceModel.Description.WsdlExporter.CallExtension(WsdlContractConversionContext contractContext, IWsdlExportExtension extension)</StackTrace>
        <Type>System.Runtime.Serialization.InvalidDataContractException</Type>
       </InnerException>
       <Message>在调用 WSDL 导出扩展过程中引发异常: System.ServiceModel.Description.DataContractSerializerOperationBehavior协定: http://tempuri.org/:IChatService</Message>
       <StackTrace>  在 System.ServiceModel.Description.ServiceMetadataBehavior.MetadataExtensionInitializer.GenerateMetadata()  在 System.ServiceModel.Description.ServiceMetadataExtension.EnsureInitialized()  在 System.ServiceModel.Description.ServiceMetadataExtension.WSMexImpl.GatherMetadata(String dialect, String identifier)  在 System.ServiceModel.Description.ServiceMetadataExtension.WSMexImpl.Get(Message request)  在 SyncInvokeGet(Object , Object[] , Object[] )  在 System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp; outputs)  在 System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)  在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)  在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&amp; rpc)  在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc&amp; rpc)  在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&amp; rpc)  在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&amp; rpc)  在 System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</StackTrace>
       <Type>System.InvalidOperationException</Type>
      </ExceptionDetail>
     </Detail>
    </Fault>
    

     

    2010年7月22日 16:34

答案

  • 是我的做法有问题,FlowDocument 这类复杂对象本来就是“未标记为可序列化”的,这也是合乎情理的,正确的做法应该是写到流中再传递。

        [DataMember]
        public Stream Content { get; set; }

    这样就没有问题了。感谢 Frank Xu Lei 的关注与回复!

    • 已标记为答案 jmper 2010年7月27日 6:12
    2010年7月27日 6:10

全部回复

  • 异常信息里提示

    无法序列化类型“System.Windows.Data.BindingExpressionBase”。可以考虑使用 DataContractAttribute 属性对其进行标记,以及使用 DataMemberAttribute 属性标记所有想要序列化的该类型的成员。有关其他支持的类型,请参阅 Microsoft .NET Framework 文档。</Message>

    System.Windows.Data.BindingExpressionBase是表示 BindingExpressionPriorityBindingExpressionMultiBindingExpression 的基类。你确定要使用这种数据类型?

    FlowDocument 的结构很像XML。

     


    Frank Xu Lei--谦卑若愚,好学若饥
    专注于.NET平台下分布式应用系统开发和企业应用系统集成
    Focus on Distributed Applications Development and EAI based on .NET
     

    老徐的网站】:http://www.frankxulei.com/

    老徐的博客】:http://www.cnblogs.com/frank_xl/

    【WCF中文技术论坛】:微软WCF中文技术论坛
    【WCF英文技术论坛】:微软WCF英文技术论坛

    2010年7月26日 7:20
    版主
  • 谢谢版主,呵呵,等了几天以为不会有人回复了呢!

    先说一下我的需求吧,客户端提供一个简单的报告编辑器(RichTextBox实现的),编辑器可以实现一些简单的文本字体、格式、段落的设置,编辑之后可以将该报告提交到服务器,因为想保留格式,所以直接使用了 RichTextBox 的 Document 对象做为数据契约的 DataMember 来传输,也就是在这里遇到了问题。

    FlowDocument 其实就是以 XAML 来描述的一个对象,不知道为什么不能正常序列化,(系统提示的信息也有问题,明明已经加了 [DataMember] 属性还提示“使用 DataMemberAttribute 属性标记所有想要序列化的该类型的成员。”)

    2010年7月26日 16:12
  • 我看提示信息

    System.Windows.Data.BindingExpressionBase是表示 BindingExpressionPriorityBindingExpressionMultiBindingExpression 的基类

    有可能是FlowDocument 的子类型出了问题。是不是有不能序列化的,才导致这个错误。

     


    Frank Xu Lei--谦卑若愚,好学若饥
    专注于.NET平台下分布式应用系统开发和企业应用系统集成
    Focus on Distributed Applications Development and EAI based on .NET
     

    老徐的网站】:http://www.frankxulei.com/

    老徐的博客】:http://www.cnblogs.com/frank_xl/

    【WCF中文技术论坛】:微软WCF中文技术论坛
    【WCF英文技术论坛】:微软WCF英文技术论坛

    2010年7月27日 1:30
    版主
  • 是我的做法有问题,FlowDocument 这类复杂对象本来就是“未标记为可序列化”的,这也是合乎情理的,正确的做法应该是写到流中再传递。

        [DataMember]
        public Stream Content { get; set; }

    这样就没有问题了。感谢 Frank Xu Lei 的关注与回复!

    • 已标记为答案 jmper 2010年7月27日 6:12
    2010年7月27日 6:10