При сериализации произвольных данных через JSON.NET любое свойство, которое является null, записывается в JSON как
"propertyName": null
Это правильно, конечно.
Однако у меня есть требование автоматически перевести все нули в значение по умолчанию, равное по умолчанию. null string должен стать String.Empty, null int? должен стать 0, null bool? должен быть false и т.д.
NullValueHandling не помогает, так как я не хочу Ignore nulls, но я также не хочу Include их (Hmm, новая функция?).
Итак, я обратился к реализации пользовательского JsonConverter.
В то время как сама реализация была легкой, к сожалению, это все еще не сработало - CanConvert() никогда не вызывается для свойства с нулевым значением, поэтому WriteJson() также не вызывается. По-видимому, нули автоматически сериализуются непосредственно в null без настраиваемого конвейера.
Например, здесь приведен пример пользовательского конвертера для нулевых строк:
public class StringConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(string).IsAssignableFrom(objectType);
}
...
public override void WriteJson(JsonWriter writer,
object value,
JsonSerializer serializer)
{
string strValue = value as string;
if (strValue == null)
{
writer.WriteValue(String.Empty);
}
else
{
writer.WriteValue(strValue);
}
}
}
Выполняя это в отладчике, я заметил, что ни один из этих методов не вызван для свойств с нулевым значением.
Попадая в исходный код JSON.NET, я обнаружил, что (по-видимому, я не занимался большой глубиной) существует специальный регистр для проверки нулей и явный вызов .WriteNull().
Для чего это стоит, я попытался реализовать пользовательский JsonTextWriter и переопределить реализацию по умолчанию .WriteNull()...
public class NullJsonWriter : JsonTextWriter
{
...
public override void WriteNull()
{
this.WriteValue(String.Empty);
}
}
Однако это не сработает, так как метод WriteNull() ничего не знает о базовом типе данных. Я уверен, что я могу вывести "" для любого нулевого значения, но это не работает хорошо, например. int, bool и т.д.
Итак, мой вопрос - не нужно ли преобразовывать всю структуру данных вручную, есть ли какое-либо решение или обходное решение для этого?