I'm trying to read values written from an opc client to the server via the OnSimpleWriteValue event. As regards "basic" values (such as int, float, string,...) there are no problems, but when I have to read "complex" values, therefore with dedicated IEncodable classes, the story changes. When writing, the server encodes the values correctly, while when reading, the value returns to me in the form of an array of bytes
Below the codes I am using
public static void HandleProperty<T, P>(this T parent, ISystemContext systemContext, P property, string propertyStateName)
where T : NodeState
where P : PropertyChanged
{
BaseVariableState variableState = (BaseVariableState)parent.FindChildBySymbolicName(systemContext, propertyStateName);
if (variableState == null) return;
//Handle value changed on service
property.ChangedByService += (obj, pn, v)
=> OnPropertyChangedByService(systemContext, variableState, v);
//Handle value changed on OPC
variableState.OnSimpleWriteValue += (ISystemContext ctx, NodeState n, ref object v)
=> OnPropertyChangedByOpc(ctx, n, property, v);
//Init value
UpdateValue(variableState, systemContext, property.GetValue());
}
public static void UpdateValue<T>(this T variableState, ISystemContext systemContext, object value)
where T : BaseVariableState
{
var type = value.GetType();
//Convert IList to IEncodeable[]
if (value is IList valueList)
{
var valueArray = Array.CreateInstance(type.GenericTypeArguments[0], valueList.Count);
valueList.CopyTo(valueArray, 0);
value = valueArray;
}
variableState.Value = value;
variableState.UpdateChangeMasks(NodeStateChangeMasks.Value);
variableState.ClearChangeMasks(systemContext, false); // notifies any monitored items that the value has changed.
}
private static ServiceResult OnPropertyChangedByOpc<P>(ISystemContext ctx, NodeState n, P property, object value)
where P : PropertyChanged
{
var test = n.FindChild(ctx, property.Name);
if (value is ExtensionObject extObj) value = extObj.DecodeBinaryValue();
if (value is ExtensionObject[] extArr)
{
var type = property.GetType().GenericTypeArguments[0];
IList tempList = Array.CreateInstance(type, extArr.Length);
for (var index = 0; index < extArr.Length; index++)
{
var valueBytes = extArr[index];
var ext = valueBytes.DecodeBinaryValue(); //Here's I am trying to Decode, value is byte[]
tempList[index] = ext;
}
value = tempList;
}
property.SetValue(value);
return ServiceResult.Good;
}
private static object DecodeBinaryValue(this ExtensionObject extensionObject)
{
using var decoder = new BinaryDecoder(extensionObject.Body as byte[], ServiceMessageContext.GlobalContext);
var decodeValue = decoder.ReadExtensionObject(null); //TODO - Fix length array error
return decodeValue;
}
What I tried
- Search for online sample & documentation
What I expect
- Convert byte[] to proper class or at least receive the value already decoded

I think this is a work around, but after some spent time I found a solution. I modified the
DecodeBinaryValueusing theReadEncodablemethodOn method handler
OnPropertyChangedByOpc, I have to modified the code too because the object returned it's not cast correctly