客户端在DataContract上调用new时如何初始化抽象基构造函数?

How to initialize abstract base constructor when client calls new on DataContract?

我正在尝试想出一个变通方法,当使用我的 WCF 服务的客户端对 DataContract 对象执行 new() 时,可以容纳抽象基 class 的构造函数被初始化。我知道 DataContract 对象是作为原始的、未初始化的对象创建的,因此没有调用构造函数。我 运行 跨越了 [OnSerializing][OnSerialized][OnDeserializing][OnDeserialized] 属性的用户,我发现序列化不支持它们WCF 的引擎,除非您明确强制它使用 XML,这在这种特定情况下是不需要的。这是我正在尝试使用的非常简化的编码示例。

[DataContract(Namespace = "http://somenamespace/Data/ContractBase/v1")]
public abstract ContractBase
{
    [DataMember(IsRequired = true)]
    public SomeDataContract BaseClassObject { get; set; }

    public string Name { get; set; }        

    public ContractBase()
    {
        BaseClassObject = new SomeDataContract("randomConstructorArgument");
        Name = "Ezra";
    }
}

[DataContract(Namespace = "http://somenamespace/Data/TheClass/v1")]
[KnownType(typeof(ContractBase))]
public sealed class TheClass : ContractBase
{
    [DataMember]
    public PetDataContract MyPet { get; set; }

    [DataMember]
    public int SomeIntProperty { get; set; }

    public TheClass()
        : base()
    {
        MyPet = new PetDataContract ("Fido");
        SomeIntProperty = -1;
    }
}

我知道执行 TheClass myClass = new TheClass(); 的客户端不会初始化基本构造函数,因为从未调用 TheClass 的构造函数。我尝试添加以下方法以在序列化发生但没有成功时触发。

private void Initialize()
{
    MyPet = new PetDataContract ("Fido");
    SomeIntProperty = -1;

    base.Initialize();
}

[OnSerializing]
private void OnSerializing(StreamingContext c)
{
    Initialize();
}

基础 class 也将具有 Initialize 方法,因此 "constructors" 将被链接。构造函数本身将更新为包括 Initialize(); 调用以使用相同的公共代码源。

有没有办法在不强制通过 XmlSerializer 完成序列化的情况下处理这个问题?我当前的解决方法是在 WCF 服务中提供一种方法来在服务器上创建对象,return post-构造函数版本。

public TheClass CreateTheClass(TheClass contract)
{
    // Calls the constructor of TheClass and its base constructor.
    return new TheClass();
}

这确实按预期工作,但由于网络 I/O 成本,我宁愿避免这是一个额外的服务调用。任何帮助将不胜感激。

谢谢!

根据 this article,您提到的属性应该可以很好地与 DataContractSerializer 配合使用。你的最后一个例子有点奇怪 - 你试图使用 OnSerializing 属性,同时说在 WCF 反序列化期间不调用构造函数。

我建议将您的方法与 OnDeserializing 标记的 Initialize 方法一起使用(或者 OnDeserialized 如果您想在反序列化完成后调用您的代码)属性。