使用小写 属性 值序列化为 JSON
Serialize to JSON with lower case property values
我有一个操作层,可以将 Entity Framework 数据库上下文注入其中。我正在通过使用 Moq 模拟数据库上下文来针对操作层编写单元测试,如 here 所述。模拟数据以 JSON 格式存储在文本文件中,这些文件是根据真实数据库中的数据创建的,因为数据有点太复杂,无法从头开始构建。
除一个小问题外,一切顺利。在测试某些查询功能时,我在区分大小写方面遇到了一些麻烦。当应用程序运行时,它将 LINQ 查询转换为 SQL;由于 like %search value%
不区分大小写,因此搜索词的大小写无关紧要。但是由于模拟数据是从 JSON 加载的并且没有经过 SQL,所以测试在不应该的时候失败了。
例如,我有两条模拟记录,一条的字段值为'Port Gamble A',另一条的字段值为'PORT GAMBLE B'。搜索 'gamble' 的单元测试无法找到任一模拟记录,搜索 'Gamble' 只能找到一个。
现在,我只是在反序列化后在名称字段上调用 .ToLower()
来解决这个问题,但是子对象中有许多文本字段我想测试搜索和调用 .ToLower()
每一个都会很痛苦。手动编辑 JSON 以小写一切更糟糕。我也不想更改 LINQ 查询以在搜索词和数据库字段上调用 .ToLower()
,因为仅针对单元测试更改查询似乎很愚蠢,并且可能会对性能产生一些影响。
有没有办法自定义序列化以强制所有字符串值都小写?我找到了很多关于如何将 属性 名称 小写的示例,而不是实际值。
编辑:嗯,这很简单。对于那些对解决方案感兴趣的人:
自定义 JSON 字符串值转换器:
public class LowerCaseJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(value.ToString().ToLower());
}
}
使用 LowerCaseJsonConverter
:
序列化 EF 实体
using (TextWriter textWriter = File.CreateText(string.Format("..\..\Test Data\Cleanup Site\{0}.json", fileName)))
{
using (JsonWriter jsonWriter = new JsonTextWriter(textWriter))
{
JsonSerializer serializer = new JsonSerializer()
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
Formatting = Formatting.Indented
};
serializer.Converters.Add(new LowerCaseJsonConverter());
serializer.Serialize(jsonWriter, entity);
}
}
我假设您正在使用 Json.Net
,您只需要使用自定义序列化程序,然后您可以将任何您想要的逻辑添加到 属性 names AND values
http://blog.maskalik.com/asp-net/json-net-implement-custom-serialization/
我有一个操作层,可以将 Entity Framework 数据库上下文注入其中。我正在通过使用 Moq 模拟数据库上下文来针对操作层编写单元测试,如 here 所述。模拟数据以 JSON 格式存储在文本文件中,这些文件是根据真实数据库中的数据创建的,因为数据有点太复杂,无法从头开始构建。
除一个小问题外,一切顺利。在测试某些查询功能时,我在区分大小写方面遇到了一些麻烦。当应用程序运行时,它将 LINQ 查询转换为 SQL;由于 like %search value%
不区分大小写,因此搜索词的大小写无关紧要。但是由于模拟数据是从 JSON 加载的并且没有经过 SQL,所以测试在不应该的时候失败了。
例如,我有两条模拟记录,一条的字段值为'Port Gamble A',另一条的字段值为'PORT GAMBLE B'。搜索 'gamble' 的单元测试无法找到任一模拟记录,搜索 'Gamble' 只能找到一个。
现在,我只是在反序列化后在名称字段上调用 .ToLower()
来解决这个问题,但是子对象中有许多文本字段我想测试搜索和调用 .ToLower()
每一个都会很痛苦。手动编辑 JSON 以小写一切更糟糕。我也不想更改 LINQ 查询以在搜索词和数据库字段上调用 .ToLower()
,因为仅针对单元测试更改查询似乎很愚蠢,并且可能会对性能产生一些影响。
有没有办法自定义序列化以强制所有字符串值都小写?我找到了很多关于如何将 属性 名称 小写的示例,而不是实际值。
编辑:嗯,这很简单。对于那些对解决方案感兴趣的人:
自定义 JSON 字符串值转换器:
public class LowerCaseJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(value.ToString().ToLower());
}
}
使用 LowerCaseJsonConverter
:
using (TextWriter textWriter = File.CreateText(string.Format("..\..\Test Data\Cleanup Site\{0}.json", fileName)))
{
using (JsonWriter jsonWriter = new JsonTextWriter(textWriter))
{
JsonSerializer serializer = new JsonSerializer()
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
Formatting = Formatting.Indented
};
serializer.Converters.Add(new LowerCaseJsonConverter());
serializer.Serialize(jsonWriter, entity);
}
}
我假设您正在使用 Json.Net
,您只需要使用自定义序列化程序,然后您可以将任何您想要的逻辑添加到 属性 names AND values
http://blog.maskalik.com/asp-net/json-net-implement-custom-serialization/