Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF Service default values

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

like image 862
Fabiano Avatar asked Jan 11 '10 12:01

Fabiano


People also ask

What is WCF behavior?

Windows Communication Foundation (WCF) configures behaviors in two ways: either by referring to behavior configurations -- which are defined in the <behavior> section of a client application configuration file – or programmatically in the calling application.

What is EmitDefaultValue C#?

Gets or sets a value that specifies whether to serialize the default value for a field or property being serialized. public: property bool EmitDefaultValue { bool get(); void set(bool value); }; C# Copy.

Is WCF stateless or stateful?

In this way, each request is served by a new service instance. It means a new service instance is created for each request and destroyed after the request is served. This make your WCF service stateless means you can't maintain states between WCF calls.


3 Answers

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();
        }
  }
like image 155
Fabiano Avatar answered Nov 12 '22 05:11

Fabiano


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"
}
like image 30
Marc Gravell Avatar answered Nov 12 '22 04:11

Marc Gravell


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.

like image 25
John Saunders Avatar answered Nov 12 '22 04:11

John Saunders