首页 文章

WCF服务默认值

提问于
浏览
10

我有我的WCF服务的以下数据 Contract 类:

[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"
}

有没有办法配置数据 Contract 的方式,定义的默认值“默认名称”不会丢失?

additional information :我在引用的程序集中使用服务引用 without 重用类型,例如在客户端,生成类MyClass DTO ,不知道服务器端类MyClass

4 回答

  • 2

    我发现这个唯一可能(但是很丑陋,因此并不真正令人满意)的解决方案是使用 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();
            }
      }
    
  • 3

    嗯..我认为有些东西可以用 [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"
    }
    
  • 1

    我不相信XML Schema允许描述元素的默认值 . 这意味着,就服务的客户而言,没有默认值 .

    除此之外,你没有告诉WCF你的意思是有一个默认值,所以即使有办法将你的意图传达给客户,事实是你没有传达你的意图 .

  • 2

    在反序列化期间,将执行属性的“set”逻辑,因此您可以在那里检查null并设置为该点所需的默认值 .

相关问题