我有WCF服务的以下数据合同类:
[DataContract(Name = "MyClassDTO")] public class MyClass { private string name = "Default Name"; [DataMember] public string Name { get { return name; } set { name = value; } } }
当我使用Visual Studio的Add Service Reference函数生成一个WCF服务引用时,生成的DataContract看起来像这样:
[System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization","3.0.0.0")] [System.Runtime.Serialization.DataContractAttribute(Name = "MyClassDTO",Namespace = "xxx")] [System.SerializableAttribute()] public partial class MyClassDTO : object,System.Runtime.Serialization.IExtensibleDataObject,System.ComponentModel.INotifyPropertyChanged { [System.Runtime.Serialization.OptionalFieldAttribute()] private string NameField; [System.Runtime.Serialization.DataMemberAttribute()] public string Name { get { return this.NameField; } set { if ((object.ReferenceEquals(this.NameField,value) != true)) { this.NameField = value; this.RaisePropertyChanged("Name"); } } } }
这意味着,默认值“Default Name”将丢失,并发生以下行为:
MyClassDTO mcdto = new MyClassDTO(); serviceClient.DoSomething(mcdto); [OperationContract] void DoSomething(MyClass mc){ mc.Name //<-- == null but I want it to be "Default Name" }
有没有办法配置数据合约的方式,定义的默认值“默认名称”不会丢失?
附加信息:
我使用服务引用,而不会在引用的程序集中重复使用类型.在客户端,MyClassDTO类生成一个不知道服务器端的MyClass类
解决方法
我发现这个唯一可能的(但是很难,但不是很令人满意)的解决方案是使用OnDeserializing属性来设置反序列化开始时的默认值,使用字段的设置器来确定是否应该设置通信值.
[DataContract(Name = "MyClassDTO")] public class MyClass { private string name; public MyClass() { Init(); } [DataMember] public string Name { get{ return name; } set { if (!String.IsNullOrEmpty(value)) { name = value; } } } private void Init() { name = "Default Name"; } [System.Runtime.Serialization.OnDeserializing] private void OnDeserializing(StreamingContext ctx) { Init(); } }