При сериализации произвольных данных через JSON.NET любое свойство, которое является null, записывается в JSON как
"propertyName" : null
Это, конечно, правильно.
Однако у меня есть требование автоматически преобразовывать все нули в пустое значение по умолчанию, например, null string
s должен стать String.Empty
, null int?
s должен стать 0
, null bool?
s должен стать false
, и так далее.
NullValueHandling
не помогает, поскольку я не хочу игнорировать
нули, но и не хочу включать
их (Хм, новая функция?).
Поэтому я обратился к реализации пользовательского 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()
ничего не знает о базовом типе данных. Так что, конечно, я могу вывести """
для любого null, но это не работает для, например, int, bool и т.д.
Итак, мой вопрос - если не преобразовывать всю структуру данных вручную, есть ли какое-нибудь решение или обходной путь для этого?