diff --git a/src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/RealMxGatewayClient.cs b/src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/RealMxGatewayClient.cs index 8435d1d6..ac7c7086 100644 --- a/src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/RealMxGatewayClient.cs +++ b/src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/RealMxGatewayClient.cs @@ -435,6 +435,21 @@ public sealed class RealMxGatewayClient : IMxGatewayClient string s => s.ToMxValue(), DateTimeOffset dto => dto.ToMxValue(), DateTime dt => dt.ToMxValue(), + // List/array attribute values. The InstanceActor decodes a canonical JSON + // List attribute into a typed List (AttributeValueCodec produces + // List) before the write so the DCL + // can push a real MXAccess array. Map each to the client's typed array + // encoder. Without these a List would fall through to Convert.ToString + // and write a garbage scalar string to an array node — which the gateway's + // COM write then rejects/blocks (the array-write hang). + IReadOnlyList lb => lb.ToMxValue(), + IReadOnlyList li => li.ToMxValue(), + IReadOnlyList ll => ll.ToMxValue(), + IReadOnlyList lf => lf.ToMxValue(), + IReadOnlyList ld => ld.ToMxValue(), + IReadOnlyList ls => ls.ToMxValue(), + IReadOnlyList ldto => ldto.ToMxValue(), + IReadOnlyList ldt => ldt.Select(d => (DateTimeOffset)d).ToList().ToMxValue(), // Fall back to invariant string for any other CLR type. _ => Convert.ToString(value, CultureInfo.InvariantCulture)!.ToMxValue(), };