Search code examples
c#web-serviceswcfdatacontract

DataContract objects in client - only simple properties are not getting lost from call to call


I have this code, a service using a DataContract. The host is build on a Web site. Please notice, the serivce is at PerSession mode:

public interface IService
{
    [OperationContract]
    int GetNewAge(Person person);
}


[DataContract]
public class Person
{
    private int age;
    [DataMember]
    public int Age
    {
        get { return age; }
        set { age = value; }
    }
    [DataMember]
    public int AgeNextYear
    {
        get { return age + 1; }
    }
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class Service : IService
{
    public int GetNewAge(Person person)
    {
        return person.AgeNextYear;
    }
}

The Client: Uses the type person:

ServiceClient c = new ServiceClient();
Person person = new Person { Age = 100 };
int curAge = person.Age;
int nextYearAge1 = person.AgeNextYear;
int nextYearAge2 = c.GetNewAge(person);

curAge - ok. - simple property works fine.

nextYearAge1 - 0, instead of 101

nextYearAge2 - program crashes...

Can any one help? Many thanks, Liron.


Solution

  • Your data contract should be a data contract. Logic like AgeNextYear does not get transfered and no proxy class can use that logic.

    You could do that if both sides of your WCF conversation were C# and you were using a data contract assembly. Then simply removing the [DataMember] attribute on AgeNextYear would work because the logic gets shared through the common contract assembly.

    Example:

    [DataContract]
    public class Person
    {
        // this is plain data. It can be transfered back and forth,
        // other languages and frameworks will have no problem 
        // building proxy classes for it
        [DataMember]
        public int Age { get; set; }
    
        // this is not data. There is no data, there only is a calculation. 
        // That's logic. Logic cannot be transfered. Lets say your age is 18, 
        // then this is 19. But the point that this is not a fixed value of 19, 
        // but actually Age + 1, cannot be transfered. It's not data. It should 
        // not be part of the contract if you want this to be usable as a 
        // generic web service.
        [DataMember]
        public int AgeNextYear
        {
            get { return Age + 1; }
        }
    }