C#enum DataMember更改其在WCF中的值

C#enum DataMember更改其在WCF中的值,c#,wcf,enums,datamember,C#,Wcf,Enums,Datamember,我有以下代码片段 [DataMember] public StateEnum DeviceState { get { return _deviceState; } set { if (IsArmed) { _deviceState = value; }

我有以下代码片段

[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
值,
但是当我在客户端中断时,对于同一个对象,我有
stateeurnm.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上起着至关重要的作用,
解除防护后,它将显示为“无法访问”。 它仍然可以通过不同的方法从不同的代码区域进行更新-但我不想显示它,只想将它保存到其他地方-并在重新启用它时显示最近的状态。
这就是我的“非对称”设置器的原因。
以下是Arm&Disarm的实现(从客户端调用)

我希望我提供了您所需要的信息。
谢谢,

Naor.

您看到这种情况是因为您的getter和setter是不对称的

似乎正在
DISCONNECTED
变量上设置
\u而isarmstate
变量的值,使
\u deviceState
变量处于其初始状态
default(StateEnum)
,这恰好是
ERROR

要解决此问题,请将数据传输对象的getter和setter更改为对称。理想情况下,从中删除所有业务逻辑,例如注意
IsArmed
状态

与其问我应该更新这个成员还是其他成员,不如让setter为我确定它

不过,该逻辑不属于DTO。当前,对象的状态取决于属性的设置顺序。当您控制设置属性的顺序时,对于业务对象来说这可能是正常的。然而,当WCF实现决定属性的设置顺序时,这对于数据传输对象是绝对不可接受的


例如,考虑传递一个武装并连接的对象。如果WCF先设置

IsArmed
,然后设置
DeviceState
,则最终会出现处于连接状态的武装对象(即一切正常)。但是,如果WCF首先设置了
设备状态
,则最终会使受保护对象处于错误状态,而
而isarmstate
设置为已连接。换言之,在传输的另一端,您会得到一个处于不同状态的对象,这正是您试图解决的问题。

第一个非常重要的一点是,您必须将实现与契约分离

保留DeviceState的标准setter和getter,并基于setter的当前代码实现单独的SetDeviceState方法

并相应地将所有引用从DeviceState=更改为SetDeviceState

之后,如果需要,如果您有可能构建和测试服务的“调试”版本,我建议您向对象添加一个临时TraceHelper属性,就像一个简单的字符串,每次更新DeviceState和IsArmed时,它都会以追加模式更新

还有可能跟踪所有调用方方法


因此,您可以更容易地发现更新序列逻辑中是否存在错误。

bool是在哪里定义的?是否在列表完成并发送时被覆盖?我怀疑您需要显示更多的代码(一个最小的、完整的、可验证的示例),感谢您的部分更新!无论如何,“它仍然可以从不同的代码区域,通过不同的方法进行更新”可能是问题的原因:)只需仔细检查客户端上的IsArmed和WhileDisarmState是否符合您的预期,或者在对象返回之前尝试查看服务器上发生的情况……我更新了我的问题。您的回答是正确的,但我这样做是为了在调用setter DeviceState时简化代码。与其问我应该更新这个成员还是其他成员,不如让setter为我确定它。
public virtual void Arm()
    {
        IsArmed = true;
        DeviceState = WhileDisarmState;
        IsUpdated = true;
    }

    public virtual void DisArm()
    {
        DeviceState = StateEnum.DISARMED;
        IsArmed = false;
        IsUpdated = true;
    }