System.Text.Json Глобальная сериализация нулевых строк в пустые строки
При переносе кода с newtonsoft json на system.text.json
Мне нужно, чтобы все строки, допускающие значение NULL, отображались как пустая строка.
Я написал следующий преобразователь, но все значения нулевой строки по-прежнему отображаются как нулевые.
А для значений нулевой строки метод Write не вызывается. Точка останова никогда не достигается.
public class EmptyStringConverter : JsonConverter<string>
{
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> Convert.ToString(reader.GetString(), CultureInfo.CurrentCulture);
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
if (writer == null)
throw new ArgumentNullException(nameof(writer));
writer.WriteStringValue(value ?? "");
}
}
Код запуска
services.AddControllers()
.AddJsonOptions(option =>
{
option.JsonSerializerOptions.Converters.Add(new EmptyStringConverter());
});
Пример консоли
class Program
{
static void Main(string[] args)
{
var jsonSerializerOptions = new JsonSerializerOptions();
jsonSerializerOptions.Converters.Add(new EmptyStringConverter());
var json = JsonSerializer.Serialize(new Model() { FirstName = null }, jsonSerializerOptions);
}
}
public class EmptyStringConverter : JsonConverter<string>
{
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> Convert.ToString(reader.GetString(), CultureInfo.CurrentCulture);
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
if (writer == null)
throw new ArgumentNullException(nameof(writer));
writer.WriteStringValue(value ?? "");
}
}
public class Model
{
public string FirstName { get; set; }
}
3 ответа
В .NET 5.0 это можно сделать, переопределивJsonConverter<T>.HandleNull
и возвращение
true
:
public class EmptyStringConverter : JsonConverter<string>
{
public override bool HandleNull => true;
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> reader.TokenType == JsonTokenType.Null ? "" : reader.GetString();
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) =>
writer.WriteStringValue(value ?? "");
}
Дополнительные сведения см. В разделе Обработка нулевых значений.
Демо скрипка здесь .
В .NET Core 3.x это не реализовано. Из Обработка нулевых значений в .NET Core 3.x:
Обрабатывать нулевые значения
По умолчанию сериализатор обрабатывает нулевые значения следующим образом:
Для справочных типов и
Nullable<T>
типы:
- Он не передает значение null пользовательским конвертерам при сериализации.
- Он не передает JsonTokenType.Null настраиваемым конвертерам при десериализации.
- Он возвращает нулевой экземпляр при десериализации.
- Он записывает null непосредственно в писатель при сериализации.
Для типов значений, не допускающих значения NULL:
- Он передает JsonTokenType.Null настраиваемым конвертерам при десериализации. (Если пользовательский преобразователь недоступен, внутренний преобразователь для типа выдает исключение JsonException.)
Такое поведение обработки нулевого значения в первую очередь предназначено для оптимизации производительности за счет пропуска дополнительного вызова преобразователя. Кроме того, он позволяет избежать принуждения преобразователей для типов, допускающих значение NULL, для проверки наличия NULL в начале каждого переопределения методов Read и Write.
Попытайся
/// <summary>
/// Convert empty to null when read data json
/// </summary>
public class EmptyStringToNullConverter : JsonConverter<string>
{
/// <summary>
/// Override CanConvert method of JsonConverter
/// This instance only convert the string type.
/// </summary>
/// <returns></returns>
public override bool CanConvert(Type typeToConvert)
{
return typeToConvert == typeof(string);
}
/// <summary>
/// Override ReadJson method of JsonConverter
/// Convert string null to empty
/// </summary>
/// <returns></returns>
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
string value = (string)reader.GetString();
return value ?? String.Empty;
}
/// <summary>
/// Override WriteJson method of JsonConverter
/// </summary>
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
throw new NotImplementedException("Unnecessary");
}
}
@ Халил, не могли бы вы дать образец кода? В моем сообществе VS2017 вызывается метод записи.
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var emptyStringConverter = new EmptyStringConverter();
emptyStringConverter.Write(null, null, null);
}
}
}
EmptyStringConverter класс:
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace ConsoleApp1
{
public class EmptyStringConverter : JsonConverter<string>
{
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
;
}
}
}