.NET Core与.NET Framework间DataTable转二进制数组数据不一致问题
.NET Core API与.NET Framework窗体应用间DataTable跨框架序列化问题
我需要在.NET Core API和.NET Framework窗体应用之间通过二进制数组交换DataTable数据,但发现两者的序列化行为存在差异,导致转换后的DataTable与API发送的数据不一致。现有以下API端C#代码和客户端VB.NET代码,希望实现转换后DataTable完全一致。
API端C#代码
public byte[] GetDataTable(string sqlStr, string connectionString) { XmlSerializer serializer = new XmlSerializer(typeof(DataTable)); DataTable dataTable = CriaDataTable(sqlStr,connectionString); using (MemoryStream memoryStream = new MemoryStream()) { serializer.Serialize(memoryStream, dataTable); return memoryStream.ToArray(); } }
客户端VB.NET代码
Public Function ApiGetDataTable(sqlStr As String, connectionString As String) As DataTable Dim url As String = $"{_baseUrl}GetDataTable?sqlStr={Uri.EscapeDataString(sqlStr)}&connectionString={Uri.EscapeDataString(connectionString)}" Dim request As New HttpRequestMessage(HttpMethod.Get, url) request.Headers.Add("accept", "application/octet-stream") Dim response = _httpClient.SendAsync(request).Result response.EnsureSuccessStatusCode() Dim content As Byte() = response.Content.ReadAsByteArrayAsync().Result Dim serializer As New XmlSerializer(GetType(DataTable)) Using memoryStream As New MemoryStream(content) Dim dataTable As DataTable = DirectCast(serializer.Deserialize(memoryStream), DataTable) Return dataTable End Using Return Nothing End Function
解决方案:改用DataTable原生XML读写方法
XmlSerializer对DataTable的序列化在.NET Framework和.NET Core之间存在行为差异(比如类型元数据的存储逻辑不同),导致反序列化后数据或结构不一致。使用DataTable内置的WriteXml和ReadXml方法可以保证跨框架兼容性,这是DataTable的标准化序列化实现,跨平台行为一致。
修改后的API端C#代码
public byte[] GetDataTable(string sqlStr, string connectionString) { DataTable dataTable = CriaDataTable(sqlStr, connectionString); using (MemoryStream memoryStream = new MemoryStream()) { // 写入DataTable的架构+数据,确保类型信息完整 dataTable.WriteXml(memoryStream, XmlWriteMode.WriteSchema); return memoryStream.ToArray(); } }
修改后的客户端VB.NET代码
Public Function ApiGetDataTable(sqlStr As String, connectionString As String) As DataTable Dim url As String = $"{_baseUrl}GetDataTable?sqlStr={Uri.EscapeDataString(sqlStr)}&connectionString={Uri.EscapeDataString(connectionString)}" Dim request As New HttpRequestMessage(HttpMethod.Get, url) request.Headers.Add("accept", "application/octet-stream") Dim response = _httpClient.SendAsync(request).Result response.EnsureSuccessStatusCode() Dim content As Byte() = response.Content.ReadAsByteArrayAsync().Result Dim dataTable As New DataTable() Using memoryStream As New MemoryStream(content) // 先读取架构再加载数据,完整还原原DataTable结构 dataTable.ReadXml(memoryStream, XmlReadMode.ReadSchema) Return dataTable End Using Return Nothing End Function
关键说明
XmlWriteMode.WriteSchema:序列化时同时写入DataTable的架构信息(列名、数据类型、约束等),保证反序列化时能精准还原结构。XmlReadMode.ReadSchema:读取时优先解析架构信息,再加载数据,确保列类型、结构和原DataTable完全匹配。- 该方式完全规避了
XmlSerializer的跨框架兼容性问题,因为WriteXml/ReadXml是DataTable的原生标准实现,在.NET Framework和.NET Core中行为统一。
内容的提问来源于stack exchange,提问作者fractaldisorder
相关产品推荐
相关产品推荐

