含空格键名的JSON无法映射C#类,SSIS导入SQL Server字段为空
处理带空格JSON键的SSIS数据导入问题
问题场景
我需要将一份JSON文件导入SQL Server,JSON结构如下:
"records": [ { "Location (Last Level)": "Calgary", "Country": "Canada" }, { "Location (Last Level)": "Coconut Creek", "Country": "United States" } ]
大部分数据能正常导入,但名称含空格和括号的键Location (Last Level)对应字段始终为空。JSON共36条记录,SSIS生成了36条SQL记录,但该字段无值,Country字段可以正常填充,我只需要解决Location (Last Level)字段的问题。
尝试过的代码
最初创建的C#类:
namespace SC_0fc0e19fc563441a96856fc8e8911872 { public class LocAPI { public string LocationLastLevel { get; set; } } public class Root { public List<LocAPI> records { get; set; } } }
后来参考帖子修改了类,添加了JsonPropertyName特性,但依然无效:
using System.Text.Json.Serialization; namespace SC_0fc0e19fc563441a96856fc8e8911872 { public class LocAPI { [JsonPropertyName("Location (Last Level)")] public string LocationLastLevel { get; set; } } public class Root { public List<LocAPI> records { get; set; } } }
主程序的反序列化代码:
var response = client.GetAsync(APIUrl).Result; if (response.IsSuccessStatusCode) { var result = response.Content.ReadAsStringAsync().Result; Root loc = new JavaScriptSerializer().Deserialize<Root>(result); foreach (var item in loc.records) { LocationAPIBuffer.AddRow(); LocationAPIBuffer.Location = item.LocationLastLevel; } }
问题根源与解决方案
问题出在序列化器不匹配:你用的是JavaScriptSerializer(属于System.Web.Script.Serialization命名空间),但JsonPropertyName是System.Text.Json库的特性,两者不兼容,所以特性不会生效。
有两种解决方式:
方式1:改用System.Text.Json序列化器
保持现有的JsonPropertyName特性,把反序列化代码换成System.Text.Json的实现:
using System.Text.Json; // ...其他代码 var response = client.GetAsync(APIUrl).Result; if (response.IsSuccessStatusCode) { var result = response.Content.ReadAsStringAsync().Result; Root loc = JsonSerializer.Deserialize<Root>(result); foreach (var item in loc.records) { LocationAPIBuffer.AddRow(); LocationAPIBuffer.Location = item.LocationLastLevel; } }
方式2:使用JavaScriptSerializer兼容的特性
如果不想换序列化器,改用DataContract和DataMember特性(需要引用System.Runtime.Serialization命名空间):
using System.Runtime.Serialization; namespace SC_0fc0e19fc563441a96856fc8e8911872 { [DataContract] public class LocAPI { [DataMember(Name = "Location (Last Level)")] public string LocationLastLevel { get; set; } } [DataContract] public class Root { [DataMember(Name = "records")] public List<LocAPI> records { get; set; } } }
主程序的反序列化代码不需要修改,依然使用JavaScriptSerializer即可。
内容的提问来源于stack exchange,提问作者Rana
相关产品推荐
相关产品推荐

