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