I have the following code snippet
[DataMember]
public StateEnum DeviceState
{
get
{
return _deviceState;
}
set
{
if (IsArmed)
{
_deviceState = value;
}
else
{
_whileDisarmState = value;
}
}
}
while IsArmed is Boolean,
and StateEnum has the following struct
[DataContract]
public enum StateEnum
{
[EnumMember]
ERROR,
[EnumMember]
CONNECTED,
[EnumMember]
DISCONNECTED,
[EnumMember]
DISARMED,
[EnumMember]
ALARM,
[EnumMember]
WARNING,
}
I have a method which invokes the server and get list of objects, which DeviceState is one of its members.
When I break on server side just before returning the list, one of the objects have a DeviceState = StateEnum.DISCONNECTED
value,
but when I break on the client side, I have for the same object the StateEunm.ERROR
value.
I'm pretty sure the problem is with the IsArmed Boolean.
Trying to DataMember it didn't help, as well as adding [KnownType(typeof(StateEnum))]
to the object itself.
One more thing, this enum is known on client side, it worked perfectly fine before adding this if statement.
I'll try to explain my logic with more code snippets,
though this is complex code, not sure I can describe it fully.
Here are the relevant properties and private members:
[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 get their initial value in the constructor:
IsArmed = true;
WhileDisarmState = StateEnum.DISCONNECTED;
DeviceState = StateEnum.DISCONNECTED;
DeviceState holds crucial part on client UI,
It is displayed as "Unreachable" when it is disarmed.
It can still be updated from different areas of code, by different methods - but I don't want to display it, just save it somewhere else - and display the recent state when it is armed again.
This is the reason for my "not symmetric" setter.
Here is the implementation for the Arm & Disarm (invoked from client side)
public virtual void Arm()
{
IsArmed = true;
DeviceState = WhileDisarmState;
IsUpdated = true;
}
public virtual void DisArm()
{
DeviceState = StateEnum.DISARMED;
IsArmed = false;
IsUpdated = true;
}
I hope I gave you as much info as you need.
Thanks,
Naor.
A first, very important point is that you have to separate the implementation from the contract.
Keep the standard setters and getters for your DeviceState and implement a separate SetDeviceState method based on the current code of your setter
and change all the references accordingly from DeviceState = to SetDeviceState
After that, in case of need, if you have the possibility to build and test a "debug" version of your service I'd suggest to add a temporary TraceHelper property to the object like a simple string that is updated in append mode each time DeviceState and IsArmed are updated
and possibly tracking also all the caller methods...
so that you can more easily spot if there has been a bug in the update sequence logic..