【问题标题】:Am I able to make non-primative .NET types serializable in WCF?我能否在 WCF 中使非原始 .NET 类型可序列化?
【发布时间】:2018-05-15 18:28:22
【问题描述】:

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

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

MyClass 在我的界面中实现每个 [OperationContract] 存根,并且我在 MyClass : MyInterface 的正上方添加了 [DataContract()] 装饰器,但是当我尝试使用 [DataMember] 装饰我的类中的 PricipalContext 成员时,Visual Studio 告诉我通过智能感知,属性“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.) System.DirectoryServices.AccountManagement.PrincipalContext 是否必须可序列化才能使 MyWCFService 类包含所述类型作为成员?创建 MyWCFService 的主要原因是在我的组织内公开 System.DirectoryServices 和 System.DirectoryServices.AccountManagement dll 的功能。

【问题讨论】:

  • 您是否尝试过围绕您要序列化的对象创建一个包装类?然后你可以序列化你的包装类。或者创建一个您序列化的类,作为底层对象的各种抽象层。
  • 我的包装器是否需要将 MyClass Member 中的每个不可序列化类型抽象为原始类型,例如:String、Bool、List
  • getter 和 setter 感觉很奇怪,但我的另一部分认为也许我需要简化解决方案的返回类型。一旦我可以访问我的 WSDL,我就会在我需要的地方。

标签: wcf datacontract


【解决方案1】:

这是设计使然。这些类型不可序列化。您可以通过创建包装类来解决此问题。您可以执行以下操作:

    [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);
        }
    }

【讨论】:

    猜你喜欢
    • 2010-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2011-02-05
    • 1970-01-01
    • 2021-12-09
    相关资源
    最近更新 更多