在 DataContracts 上使用 INotifyChanged
我试图将实际服务数据与服务功能分开,因此将数据作为包含多个属性(数据成员)的数据契约返回。客户端代码是使用 svcutil /edb 生成的,它还为代理代码生成 INotifyPropertyChanged 实现。据我的测试显示,该代码不会针对服务器上发生的更改调用 PropertyChanged 事件。此外,获取属性仅返回获取数据协定代理时的属性值。
基本上,这就是我所得到的:(
服务器端)
[ServiceContract]
public interface IControllerService
{
[OperationContract]
DataModel GetDataModel();
}
[DataContract]
public class DataModel : INotifyPropertyChanged
{
private string _state;
[DataMember]
public string State
{
set
{
if (_state != value)
{
_state = value;
OnPropertyChanged("State");
}
}
get
{
return _state;
}
}
public event PropertyChangedEventHandler PropertyChanged;
[OperationContract]
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
(客户端)
private void Test()
{
ControllerServiceClient client = new ControllerServiceClient();
DataModel model = client.GetDataModel();
model.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(DataModelChanged);
Console.WriteLine(model.State);
// ... invoke something that forces the server to change the data model
// Output stays the same
Console.WriteLine(model.State);
}
private void DataModelChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
// This method never get called for server-side changes
}
我希望数据契约代理充当服务器数据契约的透明代理,但它似乎完全不受约束。
预先非常感谢, 干杯,
罗穆特
I'm trying to separate actual service data from service functionality and am therefore returning data as a data contract which holds several properties (data members). The client code is generated using svcutil /edb which also generates an INotifyPropertyChanged implementation for the proxy code. As far as my testing revealed, that code does not invoke the PropertyChanged event for changes which happened on the server. Additionally, getting a property does only return the property value as when the data contract proxy has been obtained.
Basically, here is what I've got:
(Server Side)
[ServiceContract]
public interface IControllerService
{
[OperationContract]
DataModel GetDataModel();
}
[DataContract]
public class DataModel : INotifyPropertyChanged
{
private string _state;
[DataMember]
public string State
{
set
{
if (_state != value)
{
_state = value;
OnPropertyChanged("State");
}
}
get
{
return _state;
}
}
public event PropertyChangedEventHandler PropertyChanged;
[OperationContract]
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
(Client Side)
private void Test()
{
ControllerServiceClient client = new ControllerServiceClient();
DataModel model = client.GetDataModel();
model.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(DataModelChanged);
Console.WriteLine(model.State);
// ... invoke something that forces the server to change the data model
// Output stays the same
Console.WriteLine(model.State);
}
private void DataModelChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
// This method never get called for server-side changes
}
I expect that the data contract proxy acts as a transparent proxy to the server's data contract but it seems to be completely unbound.
Thanks very much beforehand,
Cheers,
Romout
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不要将 DataContract 视为“透明代理”,它更像是一个接口。
仅仅因为两个类实现相同的接口,并不意味着它们做完全相同的事情。 DataContract 的客户端和服务器端也是如此。
客户端(此处)是基于 DC 生成的,还包括对数据绑定有用的方面,例如 INPC 和 ObservableCollections,仅此而已,没什么神奇的。例如,如果服务器端对象上有一些计算属性,则该逻辑将不会出现在客户端上。
如前所述,如果您需要服务器在客户端上调用事件,则需要某种双向绑定/服务,没有其他方法(除了通过轮询服务器等来模拟它)。 .)
Don't think of the DataContract as a 'transparent proxy,' it's more of an interface.
Just because two classes implement the same interface, it doesn't mean they do exactly the same thing. The same is true for the client and server sides of the DataContract.
The client-side (here) is generated based on the DC, to also include DataBinding-helpful aspects, like INPC and ObservableCollections, that's it, no magic. eg if there were some calculated properties on your server-side object, that logic will not be present on the client.
As has been mentioned, if you have a need for the server to invoke events on the client, you'll need some kind of two-way binding/service, there's no other way (other than simulating it via polling the server, etc..)
WCF 不会神奇地生成到服务器端对象的连接。它只是调用 ServiceContract 中定义的任何方法并将数据返回给您。除此之外没有其他沟通渠道。
因此,在您的情况下,您需要双工服务(请参阅: http://msdn.microsoft.com/en-us/library/cc645027%28VS.95%29.aspx),手动从服务器进行任何更改回调客户端。
WCF does not magically generate hookups to the server side objects. It simply calls whatever methods are defined in your ServiceContract and returns the data to you. There is no other communication channel beyond that.
So in your scenario you would need a duplex service (see: http://msdn.microsoft.com/en-us/library/cc645027%28VS.95%29.aspx) that calls back to the client with any change from the server manually.