WCF Service default values

断了今生、忘了曾经 提交于 2019-12-23 07:46:14

问题


I have following data contract class for my WCF Service:

[DataContract(Name = "MyClassDTO")]
public class MyClass
{
    private string name = "Default Name";

    [DataMember]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
}

When I use Visual Studio's Add Service Reference function to generate a WCF Service Reference the generated DataContract looks something like this:

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

That means, the default value "Default Name" gets lost and following behavior occurs:

MyClassDTO mcdto = new MyClassDTO();
serviceClient.DoSomething(mcdto);


[OperationContract]
void DoSomething(MyClass mc){
   mc.Name //<--   == null    but I want it to be "Default Name"
}

Is there a way configure the data contract that way, that the defined default value "Default Name" doesn't get lost?

additional information: I use a service reference without reuse of types in referenced assemblys, e.g. on the client side the class MyClassDTO is generated an is not aware of the server side class MyClass


回答1:


The only possible (but ugly and therefore not really satisfying) solution I found this far is using the OnDeserializing attribute to set the default values at the start of the deserialization an use the setter of a field to determine if the communicated value should realy be set.

   [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();
        }
  }



回答2:


Hmmm.. I thought that there were some things with [DefaultValue(...)] that would work, but apparently not; I'm a bit confused why you get null, though - since you haven't told it about any default I would expect "Default Name" to get into the output. If you have some default code (or a ShouldSerialize* / *Specified) then you could try:

[DataMember(EmitDefaultValue=true)]
public string Name {
    get { return name; }
    set { name = value; }
}

But again - I'm not entirely sure why you are seeing a null in the first place.

I've just tested this with something based on the WCF template in VS2008, and it works fine:

using (var client = new Service1Client()) {
    var result = client.GetDataUsingDataContract();
    Console.Write(result.Name); // "Default Name"
}



回答3:


I don't believe that XML Schema allows the description of a default value of an element. This means that, as far as a client of your service is concerned, there is no default value.

Besides which, you've done nothing to tell WCF that you mean to have a default value, so even if there were a way to communicate your intent to a client, the fact is that you're not communicating your intent.




回答4:


During deserialization, the 'set' logic of your property will be executed, so you could check for null there and set to whatever your desired default is at that point.



来源:https://stackoverflow.com/questions/2041663/wcf-service-default-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!