Mar*_*ijn 3 c# json .net-core asp.net-core
我想从 Json 中省略空字符串属性。
这就是我所做的。
创建一个将空字符串转换为 null 的自定义转换器:
public class EmptyStringToNullConverter : JsonConverter<string>
{
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return reader.GetString();
}
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
if (value == string.Empty)
writer.WriteNullValue();
else
writer.WriteStringValue(value);
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个JsonSerializerClass,它基本上是一个包装器System.Text.Json.JsonSerializer,这个类正在使用转换器:
public class JsonSerializerClass
{
private JsonSerializerOptions serializeOptions;
private JsonSerializerOptions deserializeOptions;
public JsonSerializerClass()
{
serializeOptions = new JsonSerializerOptions();
deserializeOptions = new JsonSerializerOptions();
InitSerializer();
InitDeserializer();
}
public JsonSerializerOptions SerializeOptions => serializeOptions;
public string Serialize(object value)
{
return Serialize(value, serializeOptions);
}
public T Deserialize<T>(string json)
{
var o = System.Text.Json.JsonSerializer.Deserialize<T>(json, deserializeOptions);
if (o == null)
throw new ArgumentException($"Cannot deserialize JSON to type {typeof(T)}: {json}");
return o;
}
public static string Serialize(object value, JsonSerializerOptions options)
{
return System.Text.Json.JsonSerializer.Serialize(value, options);
}
private void InitSerializer()
{
serializeOptions.Converters.Add(new EmptyStringToNullConverter());
serializeOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
}
private void InitDeserializer()
{
deserializeOptions.PropertyNameCaseInsensitive = true;
deserializeOptions.Converters.Add(new JsonStringEnumConverter());
deserializeOptions.Converters.Add(new DateOnlyConverter());
deserializeOptions.Converters.Add(new DateOnlyNullableConverter());
deserializeOptions.Converters.Add(new IntConverter());
deserializeOptions.Converters.Add(new DecimalConverter());
deserializeOptions.IncludeFields = true;
deserializeOptions.AllowTrailingCommas = true;
deserializeOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString;
deserializeOptions.ReadCommentHandling = JsonCommentHandling.Skip;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的测试用例:
var person = new Person
{
Name = "John",
LastName = "Doe",
MiddleName = ""
};
var serializer = new JsonSerializerClass();
var json = serializer.Serialize(person);
json.ToLower().Should().NotContain(nameof(person.MiddleName).ToLower());
Run Code Online (Sandbox Code Playgroud)
我希望它MiddleName不在 json 中,因为空字符串会变为 null,并且应从 json 中删除 null 值。而是MiddleName在 json 中,带有 value null!
在 .NET 7 中,您可以使用修饰符来影响序列化过程(更多信息请参阅公告博客):
static void ExcludeEmptyStrings(JsonTypeInfo jsonTypeInfo)
{
if (jsonTypeInfo.Kind != JsonTypeInfoKind.Object)
return;
foreach (JsonPropertyInfo jsonPropertyInfo in jsonTypeInfo.Properties)
{
if (jsonPropertyInfo.PropertyType == typeof(string))
{
jsonPropertyInfo.ShouldSerialize = static (obj, value) =>
!string.IsNullOrEmpty((string)value);
}
}
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,一切都与ShouldSerialize属性有关,该属性接受value并允许您决定是否应将其序列化。
使用我上面链接的属性添加修饰符:
var jsonSerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web)
{
TypeInfoResolver = new DefaultJsonTypeInfoResolver
{
Modifiers = { ExcludeEmptyStrings }
}
};
Run Code Online (Sandbox Code Playgroud)