feat(transport): normalize List attribute values to native JSON on import

This commit is contained in:
Joseph Doherty
2026-06-16 17:50:05 -04:00
parent 5841cec958
commit e3d804a1a6
4 changed files with 178 additions and 5 deletions
@@ -0,0 +1,51 @@
using ZB.MOM.WW.ScadaBridge.Commons.Types;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ZB.MOM.WW.ScadaBridge.Transport.Serialization;
/// <summary>
/// Import-time normalization of attribute values to the native-typed JSON form.
/// <para>
/// Bundles exported before the native-typed-JSON change carry List attribute
/// values in the old quoted-element form (e.g. <c>["10","20"]</c> for an
/// <see cref="DataType.Int32"/> list). Already-exported bundle files can't be
/// rewritten, so List values are normalised on import: every DTO→entity write
/// site routes the value through <see cref="NormalizeListValue"/> so imported
/// data lands native (<c>[10,20]</c>). The central DB normalizer remains the
/// backstop for anything that slips through.
/// </para>
/// <para>
/// Non-List attributes and null/empty values pass through unchanged. A value
/// that fails to decode (malformed JSON / un-parseable element) is left exactly
/// as-is so the import still succeeds — the DB normalizer is the backstop.
/// </para>
/// </summary>
internal static class ImportValueNormalizer
{
/// <summary>
/// Returns the native-typed JSON form of a List attribute value, or the
/// value unchanged for non-List / null / empty / malformed inputs.
/// </summary>
/// <param name="value">The attribute value as carried by the bundle DTO.</param>
/// <param name="dataType">The attribute's declared data type.</param>
/// <param name="elementType">The List element type (null for scalars).</param>
public static string? NormalizeListValue(string? value, DataType dataType, DataType? elementType)
{
if (dataType != DataType.List || string.IsNullOrEmpty(value))
{
return value;
}
try
{
return AttributeValueCodec.Encode(
AttributeValueCodec.Decode(value, DataType.List, elementType));
}
catch (FormatException)
{
// Leave malformed values exactly as imported; the DB normalizer is
// the backstop. Never abort the import for a single bad value.
return value;
}
}
}