C# enum DataMember 在 WCF 中更改其值
C# enum DataMember changes its value in WCF
我有以下代码片段
[DataMember]
public StateEnum DeviceState
{
get
{
return _deviceState;
}
set
{
if (IsArmed)
{
_deviceState = value;
}
else
{
_whileDisarmState = value;
}
}
}
而 IsArmed 是布尔值,
StateEnum 具有以下结构
[DataContract]
public enum StateEnum
{
[EnumMember]
ERROR,
[EnumMember]
CONNECTED,
[EnumMember]
DISCONNECTED,
[EnumMember]
DISARMED,
[EnumMember]
ALARM,
[EnumMember]
WARNING,
}
我有一个调用服务器并获取对象列表的方法,其中 DeviceState 是其成员之一。
当我在返回列表之前在服务器端中断时,其中一个对象具有 DeviceState = StateEnum.DISCONNECTED
值,
但是当我在客户端中断时,我对同一个对象有 StateEunm.ERROR
值。
我很确定问题出在 IsArmed 布尔值上。
尝试 DataMember 它没有帮助,以及将 [KnownType(typeof(StateEnum))]
添加到对象本身。
还有一件事,这个枚举在客户端是已知的,在添加这个 if 语句之前它工作得很好。
更新
我会尝试用更多的代码片段来解释我的逻辑,
虽然这是复杂的代码,但不确定我是否可以完整地描述它。
以下是相关属性和私有成员:
[DataMember]
public bool IsArmed
{
get { return _isArmed; }
set { _isArmed = value; }
}
public StateEnum WhileDisarmState
{
get { return _whileDisarmState; }
set { _whileDisarmState = value; }
}
#region Private Members
private StateEnum _deviceState;
private bool _isArmed;
private StateEnum _whileDisarmState;
#endregion
DeviceState 和 WhileDisarmState 在构造函数中获取它们的初始值:
IsArmed = true;
WhileDisarmState = StateEnum.DISCONNECTED;
DeviceState = StateEnum.DISCONNECTED;
DeviceState 在客户端 UI,
中占有重要地位
撤防时显示为"Unreachable"。
它仍然可以通过不同的方法从不同的代码区域更新 - 但我不想显示它,只是将它保存在其他地方 - 并在它再次武装时显示最近的状态。
这就是我 "not symmetric" setter.
的原因
这是 Arm & Disarm 的实现(从客户端调用)
public virtual void Arm()
{
IsArmed = true;
DeviceState = WhileDisarmState;
IsUpdated = true;
}
public virtual void DisArm()
{
DeviceState = StateEnum.DISARMED;
IsArmed = false;
IsUpdated = true;
}
我希望我已经提供了您需要的所有信息。
谢谢,
诺尔.
你看到这种情况是因为你的getter和setter不对称。
似乎 DISCONNECTED
的值被设置在 _whileDisarmState
变量上,使 _deviceState
变量处于其初始状态 default(StateEnum)
,这恰好是ERROR
.
要解决此问题,请将数据传输对象的 getter 和 setter 更改为对称。理想情况下,从它们中删除所有业务逻辑,例如关注 IsArmed
状态。
Instead of asking should I update this member or the other, let the setter determine it for me.
不过,该逻辑不属于 DTO。目前,对象的状态取决于属性设置的顺序。当 您 控制您设置属性的顺序时,这对于业务对象可能没问题。但是,这对于数据传输对象来说是绝对不能接受的,因为 WCF 实现决定了属性的设置顺序。
例如,考虑传递一个已武装并已连接的对象。如果 WCF 首先设置 IsArmed
,然后设置 DeviceState
,您最终会得到一个处于连接状态的武装对象(即一切正常)。但是,如果 WCF 首先设置 DeviceState
,您最终会得到一个处于错误状态的装备对象,其中 _whileDisarmState
设置为已连接。换句话说,您最终会在传输的另一端得到一个处于 不同 状态的对象,这正是您要解决的问题。
首先,非常重要的一点是,您必须将 实现 与 合同 分开。
为您的 DeviceState 保留标准 setters 和 getter,并根据您的 setter
的当前代码实现单独的 SetDeviceState 方法
并相应地将所有引用从 DeviceState = 更改为 SetDeviceState
之后,如果需要,如果您有可能构建和测试服务的 "debug" 版本,我建议添加 temporary TraceHelper 属性 对象就像一个简单的字符串,每次更新 DeviceState 和 IsArmed 时都会在追加模式下更新
并且可能还会跟踪所有调用方方法...
以便您可以更轻松地发现更新序列逻辑中是否存在错误..
我有以下代码片段
[DataMember]
public StateEnum DeviceState
{
get
{
return _deviceState;
}
set
{
if (IsArmed)
{
_deviceState = value;
}
else
{
_whileDisarmState = value;
}
}
}
而 IsArmed 是布尔值,
StateEnum 具有以下结构
[DataContract]
public enum StateEnum
{
[EnumMember]
ERROR,
[EnumMember]
CONNECTED,
[EnumMember]
DISCONNECTED,
[EnumMember]
DISARMED,
[EnumMember]
ALARM,
[EnumMember]
WARNING,
}
我有一个调用服务器并获取对象列表的方法,其中 DeviceState 是其成员之一。
当我在返回列表之前在服务器端中断时,其中一个对象具有 DeviceState = StateEnum.DISCONNECTED
值,
但是当我在客户端中断时,我对同一个对象有 StateEunm.ERROR
值。
我很确定问题出在 IsArmed 布尔值上。
尝试 DataMember 它没有帮助,以及将 [KnownType(typeof(StateEnum))]
添加到对象本身。
还有一件事,这个枚举在客户端是已知的,在添加这个 if 语句之前它工作得很好。
更新
我会尝试用更多的代码片段来解释我的逻辑,
虽然这是复杂的代码,但不确定我是否可以完整地描述它。
以下是相关属性和私有成员:
[DataMember]
public bool IsArmed
{
get { return _isArmed; }
set { _isArmed = value; }
}
public StateEnum WhileDisarmState
{
get { return _whileDisarmState; }
set { _whileDisarmState = value; }
}
#region Private Members
private StateEnum _deviceState;
private bool _isArmed;
private StateEnum _whileDisarmState;
#endregion
DeviceState 和 WhileDisarmState 在构造函数中获取它们的初始值:
IsArmed = true;
WhileDisarmState = StateEnum.DISCONNECTED;
DeviceState = StateEnum.DISCONNECTED;
DeviceState 在客户端 UI,
中占有重要地位
撤防时显示为"Unreachable"。
它仍然可以通过不同的方法从不同的代码区域更新 - 但我不想显示它,只是将它保存在其他地方 - 并在它再次武装时显示最近的状态。
这就是我 "not symmetric" setter.
的原因
这是 Arm & Disarm 的实现(从客户端调用)
public virtual void Arm()
{
IsArmed = true;
DeviceState = WhileDisarmState;
IsUpdated = true;
}
public virtual void DisArm()
{
DeviceState = StateEnum.DISARMED;
IsArmed = false;
IsUpdated = true;
}
我希望我已经提供了您需要的所有信息。
谢谢,
诺尔.
你看到这种情况是因为你的getter和setter不对称。
似乎 DISCONNECTED
的值被设置在 _whileDisarmState
变量上,使 _deviceState
变量处于其初始状态 default(StateEnum)
,这恰好是ERROR
.
要解决此问题,请将数据传输对象的 getter 和 setter 更改为对称。理想情况下,从它们中删除所有业务逻辑,例如关注 IsArmed
状态。
Instead of asking should I update this member or the other, let the setter determine it for me.
不过,该逻辑不属于 DTO。目前,对象的状态取决于属性设置的顺序。当 您 控制您设置属性的顺序时,这对于业务对象可能没问题。但是,这对于数据传输对象来说是绝对不能接受的,因为 WCF 实现决定了属性的设置顺序。
例如,考虑传递一个已武装并已连接的对象。如果 WCF 首先设置 IsArmed
,然后设置 DeviceState
,您最终会得到一个处于连接状态的武装对象(即一切正常)。但是,如果 WCF 首先设置 DeviceState
,您最终会得到一个处于错误状态的装备对象,其中 _whileDisarmState
设置为已连接。换句话说,您最终会在传输的另一端得到一个处于 不同 状态的对象,这正是您要解决的问题。
首先,非常重要的一点是,您必须将 实现 与 合同 分开。
为您的 DeviceState 保留标准 setters 和 getter,并根据您的 setter
的当前代码实现单独的 SetDeviceState 方法并相应地将所有引用从 DeviceState = 更改为 SetDeviceState
之后,如果需要,如果您有可能构建和测试服务的 "debug" 版本,我建议添加 temporary TraceHelper 属性 对象就像一个简单的字符串,每次更新 DeviceState 和 IsArmed 时都会在追加模式下更新
并且可能还会跟踪所有调用方方法...
以便您可以更轻松地发现更新序列逻辑中是否存在错误..