diff --git a/src/Gemstone/Serialization.cs b/src/Gemstone/Serialization.cs
index 9b6a14adbe..1fd5978bed 100644
--- a/src/Gemstone/Serialization.cs
+++ b/src/Gemstone/Serialization.cs
@@ -73,29 +73,28 @@ private class LegacySerializationBinder : SerializationBinder
// Perform namespace transformations that occurred when migrating to the Grid Solutions Framework
// from various older versions of code with different namespaces
string newTypeName = typeName
- .Replace("TVA.", "Gemstone.")
- .Replace("GSF.TimeSeries.", "Gemstone.Timeseries.")
- .Replace("GSF.", "Gemstone.")
- .Replace("TimeSeriesFramework.", "Gemstone.Timeseries.")
+ .Replace(".TimeSeries.", ".Timeseries.") // Updated Gemstone casing for timeseries namespace
+ .Replace("GSF.Units.EE", "Gemstone.Numeric.EE") // Gemstone assembly relocation of EE namespace
+ .Replace("TVA.Units.EE", "Gemstone.Numeric.EE") // Gemstone assembly relocation of EE namespace
+ .Replace("TimeSeriesFramework.", "Gemstone.Timeseries.") // 2007 TVA Code Library "TimeSeriesFramework" namespace
.Replace("ConnectionTester.", "Gemstone.PhasorProtocols.") // PMU Connection Tester namespace
- .Replace("TVA.Phasors.", "Gemstone.PhasorProtocols.") // 2007 TVA Code Library namespace
- .Replace("Tva.Phasors.", "Gemstone.PhasorProtocols.") // 2008 TVA Code Library namespace
- .Replace("BpaPdcStream", "BPAPDCstream") // 2013 GSF uppercase phasor protocol namespace
- .Replace("FNet", "FNET") // 2013 GSF uppercase phasor protocol namespace
- .Replace("Iec61850_90_5", "IEC61850_90_5") // 2013 GSF uppercase phasor protocol namespace
- .Replace("Ieee1344", "IEEE1344") // 2013 GSF uppercase phasor protocol namespace
- .Replace("IeeeC37_118", "IEEEC37_118"); // 2013 GSF uppercase phasor protocol namespace
+ .Replace("TVA.Phasors.", "Gemstone.PhasorProtocols.") // 2007 TVA Code Library "Phasors" namespace
+ .Replace("Tva.Phasors.", "Gemstone.PhasorProtocols.") // 2008 TVA Code Library "Phasors" namespace
+ .Replace("GSF.", "Gemstone.") // 2013+ GSF root namespace
+ .Replace("TVA.", "Gemstone.") // 2007 TVA Code Library root namespace
+ .Replace("Tva.", "Gemstone.") // 2008 TVA Code Library root namespace
+ .Replace("BpaPdcStream", "BPAPDCstream") // 2013 updated GSF casing for phasor protocol namespace
+ .Replace("FNet", "FNET") // 2013 updated GSF casing for phasor protocol namespace
+ .Replace("Iec61850_90_5", "IEC61850_90_5") // 2013 updated GSF casing for phasor protocol namespace
+ .Replace("Ieee1344", "IEEE1344") // 2013 updated GSF casing for phasor protocol namespace
+ .Replace("IeeeC37_118", "IEEEC37_118"); // 2013 updated GSF casing for phasor protocol namespace
- // Check for 2009 TVA Code Library namespace
+ // Check for 2009 TVA Code Library "PhasorProtocols" namespace
if (newTypeName.StartsWith("PhasorProtocols", StringComparison.Ordinal))
newTypeName = "Gemstone." + newTypeName;
- // Check for 2014 LineFrequency type
- if (newTypeName.Equals("GSF.PhasorProtocols.LineFrequency", StringComparison.Ordinal))
- newTypeName = "Gemstone.Numeric.EE.LineFrequency";
-
- // Check for GSF LineFrequency type
- if (newTypeName.Equals("GSF.Units.EE.LineFrequency", StringComparison.Ordinal))
+ // Check for 2014 LineFrequency type (note: already replaced GSF with Gemstone here)
+ if (newTypeName.Equals("Gemstone.PhasorProtocols.LineFrequency", StringComparison.Ordinal))
newTypeName = "Gemstone.Numeric.EE.LineFrequency";
try
@@ -128,8 +127,45 @@ private class LegacySerializationBinder : SerializationBinder
// No type found; return null
return null;
}
+
+ ///
+ /// Controls the binding of a serialized object to a type name and assembly name during serialization.
+ ///
+ ///
+ /// Maps current Gemstone types back to their legacy GSF names so that XML written by Gemstone code
+ /// remains readable by .NET Framework consumers (PMU Connection Tester, older openPDC builds, etc.)
+ /// that only know the GSF-era types. The Gemstone-side reader translates these names back via
+ /// , so round-trip identity is preserved.
+ ///
+ /// The runtime type being serialized.
+ /// On return, the legacy assembly name to emit.
+ /// On return, the legacy fully-qualified type name to emit.
+ public override void BindToName(Type serializedType, out string? assemblyName, out string? typeName)
+ {
+ string fullName = serializedType.FullName ?? serializedType.Name;
+ string typeNamespace = serializedType.Namespace ?? string.Empty;
+ string runtimeAssembly = serializedType.Assembly.GetName().Name ?? string.Empty;
+
+ // Special case: Gemstone.Numeric.EE.* types (LineFrequency, PhasorType, etc.) historically
+ // lived in the GSF.Units.EE namespace inside the GSF.Core assembly.
+ if (typeNamespace == "Gemstone.Numeric.EE" || typeNamespace.StartsWith("Gemstone.Numeric.EE.", StringComparison.Ordinal))
+ {
+ typeName = fullName.Replace("Gemstone.Numeric.EE", "GSF.Units.EE", StringComparison.Ordinal);
+ assemblyName = "GSF.Core";
+ return;
+ }
+
+ // General case: Gemstone.* → GSF.* (and Timeseries → TimeSeries casing flip).
+ typeName = fullName
+ .Replace("Gemstone.Timeseries.", "GSF.TimeSeries.", StringComparison.Ordinal)
+ .Replace("Gemstone.", "GSF.", StringComparison.Ordinal);
+
+ assemblyName = runtimeAssembly
+ .Replace("Gemstone.Timeseries", "GSF.TimeSeries", StringComparison.Ordinal)
+ .Replace("Gemstone.", "GSF.", StringComparison.Ordinal);
+ }
}
-
+
///
/// Gets value for specified ; otherwise .
///