我是否能够在WCF中将非主要.NET类型序列化?

时间:2018-05-15 18:28:23

标签: wcf datacontract

当我尝试通过url~ / MyNamespace.MyServiceClass.svc从公司内部网上的Web浏览器访问myWCF服务时,收到以下消息:

键入' System.DirectoryServices.AccountManagement.PrincipalContext'无法序列化。请考虑使用DataContractAttribute属性对其进行标记,并使用DataMemberAttribute属性标记要序列化的所有成员。如果类型是集合,请考虑使用CollectionDataContractAttribute对其进行标记。有关其他受支持的类型,请参阅Microsoft .NET Framework文档。

MyClass在我的界面中实现了每个[OperationContract]存根,我在MyClass:MyInterface的正上方添加了[DataContract()]装饰器,但是当我尝试用[DataMember]装饰我的类中的PricipalContext成员时,Visual Studio告诉我通过intellisense认为属性' DataMember'在此声明类型上无效,它仅对属性,索引器和字段声明有效。

    public PrincipalContext GetPrincipalContext()
    {
        PrincipalContext principalContext = new PrincipalContext(
            ContextType.Domain, GetUserDomainName()
        );
        return principalContext;
    }

https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.datacontractattribute?view=netframework-4.7.2

我不确定MSDN文档中的一些内容(如上所述),它们表示DataContract属性的要点:"指定类型定义或实现数据协定,并且可由序列化程序序列化,例如作为DataContractSerializer。要使其类型可序列化,类型作者必须为其类型定义数据协定。"

1。)当我不是所述类类型的作者(System.DirectoryServices.AccountManagement.PrincipalContext)时,我应该如何从.NET框架生成可序列化的预先存在的非主要类类型

2.。)我在MSDN上找到的所有示例都解决了这个问题,但仅提供了实现用户创建的自定义类类型(如Person())的示例。

3.。)对于MyWCFService类,System.DirectoryServices.AccountManagement.PrincipalContext是否必须可序列化以包含所述类型作为成员?创建MyWCFService的主要原因是从组织内的System.DirectoryServices和System.DirectoryServices.AccountManagement dll公开功能。

1 个答案:

答案 0 :(得分:0)

这是设计的。这些类型不可序列化。您可以通过创建包装类来解决此问题。你可以这样做:

    [DataContract]
    public class MyClass
    {
        public PrincipalContext PrincipalContext { get; set; }

        [DataMember(Name="PrincipalContext")]
        public PrincipalContextSurrogate PrincipalContextWrapper
        {
            get
            {
                return new PrincipalContextSurrogate(PrincipalContext);
            }
            set
            {
                PrincipalContext = value.ToPrincipalContext();
            }
        }
    }

    [DataContract]
    public class PrincipalContextSurrogate
    {
        public PrincipalContextSurrogate() { }

        public PrincipalContextSurrogate(PrincipalContext context)
        {
            ContextType = context.ContextType;
            Name = context.Name;
        }

        [DataMember]
        public ContextType ContextType { set; get; }

        [DataMember]
        public string Name { set;  get; }

        public PrincipalContext ToPrincipalContext()
        {
            return new PrincipalContext(ContextType, Name);
        }
    }