我的WCF服务有以下数据合约类:
[DataContract(Name = "MyClassDTO")]
public class MyClass
{
private string name = "Default Name";
[DataMember]
public string Name
{
get { return name; }
set { name = value; }
}
}
当我使用Visual Studio的“添加服务引用”函数生成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");
}
}
}
}
这意味着,默认值“默认名称”会丢失并发生以下行为:
MyClassDTO mcdto = new MyClassDTO();
serviceClient.DoSomething(mcdto);
[OperationContract]
void DoSomething(MyClass mc){
mc.Name //<-- == null but I want it to be "Default Name"
}
有没有办法以这种方式配置数据合同,定义的默认值“默认名称”不会丢失?
其他信息: 我在引用的程序集中使用服务引用而不重用类型,例如在客户端,生成类MyClass DTO ,不知道服务器端类MyClass
答案 0 :(得分:3)
我发现这个唯一可能(但很丑陋但因此并不令人满意)的解决方案是使用OnDeserializing
属性在反序列化开始时设置默认值并使用字段的setter来确定是否应该确定所传达的价值。
[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();
}
}
答案 1 :(得分:2)
嗯......我认为有些[DefaultValue(...)]
可以使用,但显然不行;我有点困惑,为什么你得到null
,因为你还没有告诉它任何默认我希望"Default Name"
进入输出。如果您拥有某些默认代码(或ShouldSerialize*
/ *Specified
),那么您可以尝试:
[DataMember(EmitDefaultValue=true)]
public string Name {
get { return name; }
set { name = value; }
}
但是再次 - 我不完全确定你为什么首先看到null
。
我刚用VS2008中的WCF模板测试了这个,它运行正常:
using (var client = new Service1Client()) {
var result = client.GetDataUsingDataContract();
Console.Write(result.Name); // "Default Name"
}
答案 2 :(得分:2)
我不相信XML Schema允许描述元素的默认值。这意味着,就服务的客户而言, 没有默认值。
除此之外,你没有告诉WCF你的意思是有一个默认值,所以即使有办法将你的意图传达给客户,事实是你没有传达你的意图。
答案 3 :(得分:1)
在反序列化期间,将执行属性的“set”逻辑,因此您可以在那里检查null并设置为此时所需的默认值。