WCF DataContract中的构造函数未反映在客户端上

Sub*_*sis 9 wcf datacontract

当我在客户端上创建DataContract的实例时,我需要让一些数据成员获得一些值.使用构造函数不会发生这种情况.我搜索了不同的论坛,发现我们必须使用[OnDeserializing]和[OnDeserialized]属性.这也行不通.有人可以在这里提出一些建议.另一种方法是在客户端的部分类中创建构造函数.我想避免这种情况.

请找到以下代码:

服务器端:Datacontract

[DataContract]
public class Account
{

    private int mAccountId;
    private string mAccountName;

    public Account()
    {
        mAccountId = 5;
        mAccountName = "ABC";
    }

    [OnDeserializing]
    public void OnDeserializing(StreamingContext context)
    {
        mAccountId = 5;
        mAccountName = "ABC"; 
    }

    [OnDeserialized]
    public void OnDeserialized(StreamingContext context) 
    {

    } 

    [DataMember]
    public int AccountId
    {
        get
        {
            return mAccountId;
        }
        set
        {
            mAccountId = value;
        }
    }

    [DataMember]
    public string AccountName
    {
        get
        {
            return mAccountName;
        }
        set
        {
            mAccountName = value;
        }
    }


}
Run Code Online (Sandbox Code Playgroud)

客户端 - 初始化

namespace TestClient
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Account acc = new Account();

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Mat*_*ott 15

用于创建WCF代理类的代码生成器创建兼容的合同类型,并且不使用与WCF服务使用的完全相同的类型.实现您想要的最简单方法是在您的客户端上自己创建构造函数,因为生成的代码是partial:

partial class Account
{
    public Account()
    {
        AcountId = 5;
        AccountName = "ABC";
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您不想这样做,您可以让WCF重用已经由客户端项目引用的类型.因此,如果您的数据协定类位于单独的库中(如建议的那样),则可以引用该库,然后重新配置WCF客户端项目以重用引用的程序集中的共享类型.

  • 将datacontract类放入另一个库中的+1.我们已经将它们放在具有服务接口定义的库中,并且实际上通信合同是服务问题,而不是域模型的关注. (2认同)

Sam*_*der 14

属性归属的DataMember属性仅定义生成的WSDL/XSD中包含的内容.客户端将基于wsdl/xsd 生成自己的类,以用于与服务进行通信.它不使用服务器上使用的相同类.

这就是为什么你不会得到:

  • DataContract类中定义的任何构造函数
  • 任何私有[DataMember]属性/字段(客户端将始终生成公共属性/字段)
  • DataContract类中定义的任何行为

想象一下java客户端想要连接到您的服务的场景.您是否期望使用相同的构造函数生成java类?怎么样与[OnDeserialized]属性?那么java脚本客户端或python客户端呢?

当你开始考虑它用这种方式,你开始明白为什么你不能拥有你想要的东西(至少在没有客户端和服务器之间共享库).

实际情况是,您不能强制客户端拥有始终具有默认值的类,并且您不能让客户端始终发回有效数据,客户端总是可以发送包含垃圾的消息(如果需要).您可以使用IsRequired和'EmitDefaultValue` 稍微控制消息的某些方面,它会将检查添加到xsd以确保消息中存在某些内容,但您必须在服务器上进行验证,您不能假设您将获得的对象将被验证.

我的建议是从您的域对象创建DTO以通过线路发送,其中不包含任何类型的检查,它们只是用于保存数据的简单包.然后创建工厂以将域对象转换为DTO和DTO到客户端对象.工厂只需获取DTO并将成员传递给域对象的构造函数.然后,您的验证逻辑可以存在于它所属的域对象的构造函数中.使用您目前拥有的方法,您可能会稍微扭曲验证,因此可以从构造函数和[OnDeserialized]方法完成.