![](/img/trans.png)
[英]Does JsonStringEnumConverter (System.Text.Json) support null values?
[英]System.Text.Json custom null values
我正在使用 api 端點,它們在某些字段中返回無效響應,而不是小數的 null 值。 這是一個例子
{
"name": "MyName",
"decimalOne": "0.01",
"decimalTwo": "None",
"decimalThree": "-"
}
我希望我的代碼能夠處理他們發送給我的這些自定義“null”事物,就像普通的 null 一樣。 我有辦法做到這一點嗎?
你可以嘗試這樣的事情,(我不知道你有多少個不同的十進制字段)
Name name=System.Text.Json.JsonSerializer.Deserialize<Name>(json);
public class Name
{
public string name {get; set;}
[JsonPropertyName("decimalOne")]
public string decimalOneString { get; set;}
[System.Text.Json.Serialization.JsonIgnore]
public decimal? decimalOne
{
get { if (decimal.TryParse(decimalOneString, out var result)) return result;
return null;
}
set { decimalOneString = value.ToString();}
}
}
我決定使用我們可以傳入的其他“null”參數來做一個 NullableConverterFactory。
看起來像這樣。
/// <summary>
/// Converter that can parse nullable types. int? decimal? etc
/// </summary>
public class NullableConverterFactory : JsonConverterFactory
{
private static readonly byte [] EMPTY = Array.Empty<byte>();
private static readonly HashSet<byte[]> NULL_VALUES = new()
{
EMPTY
};
/// <summary>
/// empty constructor.
/// </summary>
public NullableConverterFactory()
{
}
/// <summary>
/// Supply additional accepted null values as byte[] here.
/// </summary>
/// <param name="additionalNullValues"></param>
public NullableConverterFactory(HashSet<byte[]> additionalNullValues)
{
foreach (byte[] nullValue in additionalNullValues)
{
NULL_VALUES.Add(nullValue);
}
}
/// <summary>
/// Returns true if this converter can convert the value.
/// </summary>
/// <param name="typeToConvert"></param>
/// <returns></returns>
public override bool CanConvert(Type typeToConvert) => Nullable.GetUnderlyingType(typeToConvert) != null;
public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options) =>
(JsonConverter)Activator.CreateInstance(
typeof(NullableConverter<>).MakeGenericType(
new Type[] { Nullable.GetUnderlyingType(type) }),
BindingFlags.Instance | BindingFlags.Public,
binder: null,
args: new object[] { options, NULL_VALUES },
culture: null);
class NullableConverter<T> : JsonConverter<T?> where T : struct
{
private readonly HashSet<byte[]> _nullValues;
// DO NOT CACHE the return of (JsonConverter<T>)options.GetConverter(typeof(T)) as DoubleConverter.Read() and DoubleConverter.Write()
// DO NOT WORK for nondefault values of JsonSerializerOptions.NumberHandling which was introduced in .NET 5
public NullableConverter(JsonSerializerOptions options, HashSet<byte[]> nullValues)
{
_nullValues = nullValues;
}
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.String)
{
return JsonSerializer.Deserialize<T>(ref reader, options);
}
foreach (byte[] nullValue in _nullValues)
{
if (reader.ValueTextEquals(nullValue))
{
return null;
}
}
return JsonSerializer.Deserialize<T>(ref reader, options);
}
public override void Write(Utf8JsonWriter writer, T? value, JsonSerializerOptions options) =>
JsonSerializer.Serialize(writer, value.Value, options);
}
}
用法:
new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true,
Converters =
{
new NullableConverterFactory(new HashSet<byte[]>
{
Encoding.UTF8.GetBytes("-"),
Encoding.UTF8.GetBytes("None")
})
},
NumberHandling = JsonNumberHandling.AllowReadingFromString,
AllowTrailingCommas = true
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.