我正在尝试提出一种解决方法,当使用我的WCF服务的客户端对DataContract对象执行new()
时,该解决方法将容纳正在初始化的抽象基类构造函数。我知道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();
}
基类也将具有Initialize方法,以便链接“构造函数”。构造函数本身将更新为包含Initialize();
调用以使用相同的常见代码源。
有没有办法处理这个问题而不强制通过XmlSerializer
完成序列化?我目前的解决方法是在WCF服务中提供一个方法来在服务器上创建对象并返回构造函数后的版本。
public TheClass CreateTheClass(TheClass contract)
{
// Calls the constructor of TheClass and its base constructor.
return new TheClass();
}
这确实按预期工作,但这是一个额外的服务调用,我宁愿避免因为网络I / O成本。任何帮助都将非常感激。
谢谢!
答案 0 :(得分:0)
根据this article,您提到的属性应与DataContractSerializer
很好地配合使用。您的上一个示例有点奇怪 - 您正在尝试使用OnSerializing
属性,同时说WCF在反序列化期间不会调用构造函数。
我建议您使用Initialize
标记为OnDeserializing
的方法(如果您希望在反序列化完成后调用代码,则为OnDeserialized
)属性。