0
votes

I'm asking this out of ideas. Looked on Google a lot, did some tests myself but nothing.

I'm building some widely used WCF webservices which will be called both from .NET 2.0 clients through ASMX service reference and some newer .NET 4.5.2 clients thought a WCF service reference (Yes, I made them interoperable by just changing the endpoint in the config file).

After quite some research, the most useful stuff I found is THIS, which basically says that after .NET 3.5 SP1, you basically don't need to specify the DataContract because the framework will take care of it if you don't specify it, automatically making the data contract for custom classes. The downside is that you have to renounce to some advanced features and customizations.

This is true as I tried to make a test project with .NET 4.5.2 with some random objects and all works fine without the need of specifying the data contract.

I then tried to pass the project to .NET 3.0 and it was still working with any data contract ever....

Moreover, from the link I passed:

without [DataMember], you cannot serialize non-public properties or fields

Which happens to be not true either

Questions are:

1) Can I Specify the DataContract on a separate project and NOT into the WCF? (Example: Adding the DataContract to the objects in the class library that contains the objects that client and webservice must exchange, and expect the WCF service to understand that that object has a datacontract to use)

2) Why use DataContract if even in it's not necessary and I don't need fancy stuff? Can I go the easy way?

3) Why if I convert a project from 4.5.2 to 3.0 and vice versa the WCF continues working seamlessly? Shouldn't the DataContracts be compulsory before .NET 3.5 SP1?

4) Both with DataContract or not, I keep seeing the private fields of the objects... while guidelines says I shouldnt... WHAT?

I Really need an answer to the first one.

Here's the code of the project I used to make tests

Class library with custom objects. This is referenced in WCF and in a WinForms test client

public class MyTestObjs
{

    public class TestObject1
    {

        public string Test1 { get; private set; }
        public List<int> Test2 { get; private set; }
        private TestObject2 Test3 { get; set; }

        public TestObject1()
        {

            this.Test1 = "HELLO " + new Random().Next(2333);
            this.Test2 = new List<int> { 1, 2, 3, 43, 544, 64 };
            this.Test3 = new TestObject2();
        }
    }

    private class TestObject2
    {

        public string Test1 { get; private set; }
        public List<int> Test2 { get; private set; }

        public TestObject2()
        {

            this.Test1 = "YYYYYYYY " + new Random().Next(2333);
            this.Test2 = new List<int> { 1111, 2222, 3333, 4443, 55544, 64344 };
        }
    } 
}

WCF Service exposed methods:

public string ReturnComplexTest1(ComplexObjTest.MyTestObjs.TestObject1 test)   
{

    string result = String.Empty;
    result += test.Test1 + "_____";

    foreach (int x in test.Test2)
    {
        result += x.ToString() + " - ";
    }

    return result;
}

public ComplexObjTest.MyTestObjs.TestObject1 ReturnComplexTest1Obj()
{

    return new ComplexObjTest.MyTestObjs.TestObject1();
}

Winforms Test Client with service reference

public string ReturnComplexTest1(ComplexObjTest.MyTestObjs.TestObject1 test)
{

    string result = String.Empty;
    result += test.Test1 + "_____";

    foreach (int x in test.Test2)
    {
        result += x.ToString() + " - ";
    }

    return result;
}

public ComplexObjTest.MyTestObjs.TestObject1 ReturnComplexTest1Obj()
{

    return new ComplexObjTest.MyTestObjs.TestObject1();
}

As you can see from debugging with all the projects set to .NET 3.0 framework and NO DATACONTRACTS ANYWHERE IN THE CODE, this is the result:

screenshot

I didnt' need to specify any datacontract, and I CAN SEE private fields... This doesn't sound right but it works flawlessly bot in 4.5.2 and 3.0 NET Framework. What am I missing?

1

1 Answers

0
votes

1. Yes you can. You must add a reference to the separate project in your service contract and use the model in the contracts. Remember that contract is the part that will define which data your service will serialize, and the models can be in other project.

2. Since Framework 3.5 SP1, DataContract is no longer necessary to serialize. DataContract attribute is used to instruct the serializer which members can be serialized and give some instructions to serializer about how to serialize. As it's no longer necessary, all public members of a class in contract will be serialized. Anyway, not using DataContrat/DataMember attributes makes you miss a some interesting things: - You cannot define namespaces;
- You cannot set a member as required, set its data type and other DataMember level attributes for validation;
- You cannot set serialization order for the members;
- You cannot serialize non-public members.
So, it's up to you use or not DataContract/DataMember attributes, depending on you need some of the features above.

3. As I could see in your code, you've defined the target framework to your client (CallWCFTest project), not in the the server, where are the contracts, so it will not affect the serialization.

4. This is strange, I think you can only see the property in inspector, but are you able to use these private members in client?

Hope it helps.