首页 文章

WCF可以将DataContract仅限客户端吗? .NET Framework 3.5之后是否真的有必要?

提问于
浏览
0

我问这个想法 . 在Google上看了很多,自己做了一些测试,但没有 .

我正在构建一些广泛使用的WCF Web服务,它们将通过ASMX服务引用从.NET 2.0客户端调用,而一些较新的.NET 4.5.2客户端则认为是WCF服务引用(是的,我通过更改 endpoints 使其可以互操作配置文件) .

经过一番研究,我找到的最有用的东西是THIS,基本上说在.NET 3.5 SP1之后,你基本上不需要指定 DataContract ,因为如果你没有指定它,框架会处理它,自动为自定义类创建数据协定 . 缺点是你必须放弃一些高级功能和自定义 .

这是正确的,因为我尝试使用.NET 4.5.2使用一些随机对象进行测试项目,并且所有工作正常而无需指定数据协定 .

然后我尝试将项目传递给.NET 3.0,它仍然在处理任何数据 Contract ....

而且,从我通过的链接:

如果没有[DataMember],则无法序列化非公共属性或字段

这也不是真的

问题是:

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?

我真的需要回答第一个问题 .

这是我用来进行测试的项目代码

包含自定义对象的类库 . 这在WCF和WinForms测试客户端中引用

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服务公开的方法:

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

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

正如您在调试中看到的那样,所有项目都设置为.NET 3.0框架,并且在代码中无任何DATACONTRACTS,结果如下:

screenshot

我没有'需要指定任何datacontract,我可以看到私人领域......这听起来不对,但它在4.5.2和3.0 .NET Framework中完美无瑕地运行 . 我错过了什么?

1 回答

  • 0

    1. 是的,你可以 . 您必须在服务 Contract 中添加对单独项目的引用,并在 Contract 中使用该模型 . 请记住, Contract 是定义服务将序列化的数据的部分,模型可以在其他项目中 .

    2. 自Framework 3.5 SP1起,不再需要 DataContract 进行序列化 . DataContract属性用于指示序列化程序可以序列化哪些成员,并向序列化程序提供有关如何序列化的一些说明 . 由于不再需要, Contract 中所有公共成员都将被序列化 . 无论如何,不使用DataContrat / DataMember属性会让你错过一些有趣的事情: - 你无法定义命名空间;

    • 您无法根据需要设置成员,设置其数据类型和其他DataMember级别属性以进行验证;
    • 您无法为成员设置序列化顺序;
    • 您无法序列化非公开成员 .
      因此,您可以使用或不使用DataContract / DataMember属性,具体取决于您是否需要上述某些功能 .

    3. 正如我在您的代码中看到的那样,您已将目标框架定义到您的客户端(CallWCFTest项目),而不是在服务器中, Contract 在哪里,因此它不会影响序列化 .

    4. 这很奇怪,我认为你只能在督察中看到这个属性,但你能在客户端使用这些私人成员吗?

    希望能帮助到你 .

相关问题