WCF DataContract中的构造方法未反映在Client上

问题描述

| 在客户端上创建DataContract的实例时,我需要让一些数据成员获得一些值。使用构造函数不会发生这种情况。我搜索了不同的论坛,发现我们必须使用[OnDeserializing]和[OnDeserialized]属性。这也不起作用。有人可以在这里提出一些建议。另一种选择是在客户端的部分类中创建构造函数。我想避免这种情况。 请在下面找到代码: 服务器端:数据合同
[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;
        }
    }


}
客户端-初始化
namespace TestClient
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender,EventArgs e)
        {
            Account acc = new Account();

        }
    }
}
    

解决方法

        用于创建WCF代理类的代码生成器将创建兼容的合同类型,并且未使用与WCF服务使用的类型完全相同的类型。实现所需目标的最简单方法是在客户端上自行创建构造函数,因为生成的代码为
partial
partial class Account
{
    public Account()
    {
        AcountId = 5;
        AccountName = \"ABC\";
    }
}
如果您不想这样做,则可以使WCF重用客户项目已经引用的类型。因此,如果您的数据协定类在单独的库中(建议使用),则可以引用该库,然后重新配置WCF客户端项目以重用引用的程序集中的共享类型。     ,        带有“ 4”属性的属性仅定义将在生成的WSDL / XSD中包含的属性。客户端将基于wsdl / xsd生成自己的类,以用于与服务进行通信。它没有使用服务器上使用的相同类。 这就是为什么您不会得到:
DataContract
类中定义的任何构造函数 任何私有的“ 6”属性/字段(客户端将始终生成公共属性/字段)
DataContract
类中定义的任何行为 想象一下Java客户端想要连接到您的服务的情况。您是否希望使用相同的构造函数来生成Java类?
[OnDeserialized]
属性又如何呢? Java脚本客户端或python客户端呢? 当您开始以这种方式进行思考时,您会开始明白为什么不能拥有想要的东西(至少在没有客户端和服务器之间共享库的情况下)。 现实情况是,您不能强制客户端具有始终具有默认值的类,并且不能让客户端始终发送回有效数据,客户端始终可以只发送包含垃圾的消息(如果需要)。您可以使用
IsRequired
和\'EmitDefaultValue`来控制消息的某些方面,这将在xsd中添加检查以确保消息中存在某些内容,但是您必须在服务器上进行验证,您可以\不要假设您取回的对象将得到验证。 我的建议是从您的域对象创建DTO,以通过导线发送,其中不包含任何形式的检查,它们只是用于保存数据的简单包。然后创建工厂以将您的域对象转换为DTO,并将DTO转换为客户端对象。工厂只需获取DTO,然后将成员传递到域对象的构造函数中。然后,您的验证逻辑可以存在于它所属的域对象的构造函数中。使用当前使用的方法,您可能最终会稍微扭曲验证,以便可以从构造函数和[OnDeserialized]方法中完成验证。     ,        在客户端创建Proxy类:
public class AccountProxy: Account
{
   public AccountProxy()
   {
         mAccountId = 5;
         mAccountName = \"ABC\";
   }
}
并使用您的代理类,而不是生成的客户端类:
namespace TestClient
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender,EventArgs e)
        {
            AccountProxy acc = new AccountProxy();

        }
    }
}