Serialisieren von null in JSON.NET
Beim serialisieren beliebiger Daten über JSON.NET jede Eigenschaft, die null ist geschrieben, um die JSON als
"propertyName" : null
Dies ist richtig, natürlich.
Allerdings habe ich eine Anforderung, automatisch übersetzen alle null-Werte in die leeren Standard-Wert, z.B. null string
s sollte String.Empty
null int?
s sollte 0
null bool?
s sollte false
, und so weiter.
NullValueHandling
ist nicht hilfreich, da ich nicht wollen, zu Ignore
null, aber weder möchte ich Include
(Hmm, neues feature?).
Also wandte ich mich an die Implementierung einer benutzerdefinierten JsonConverter
.
Während die Durchführung selbst war ein Kinderspiel, leider ist dieser immer noch nicht funktioniert - CanConvert()
wird niemals aufgerufen, wenn eine Eigenschaft, die einen null-Wert, und daher WriteJson()
ist nicht genannt. Offenbar Nullen werden automatisch serialisiert direkt in null
, ohne die benutzerdefinierte pipeline.
Zum Beispiel, hier ist ein Beispiel eines benutzerdefinierten Konverter für null-Zeichenfolgen:
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);
}
}
}
Durchlaufen diese im debugger habe ich festgestellt, dass keine dieser Methoden aufgerufen, für Eigenschaften, die einen null-Wert.
Eintauchen in JSON.NET's sourcecode, fand ich, dass (anscheinend, ich nicht gehen in eine Menge von Tiefe) es ist ein Sonderfall null-Werte überprüfen, und ausdrücklich den Aufruf .WriteNull()
.
Für was es Wert ist, ich habe versucht, die Implementierung einer benutzerdefinierten JsonTextWriter
und überschreiben der Standard - .WriteNull()
Umsetzung...
public class NullJsonWriter : JsonTextWriter
{
...
public override void WriteNull()
{
this.WriteValue(String.Empty);
}
}
Jedoch, dies kann nicht gut funktionieren, da die WriteNull()
Methode weiß nichts über die zugrunde liegenden Datentyp. So sicher, ich kann die Ausgabe ""
für jeden null, aber das funktioniert nicht gut für z.B. int, bool, etc.
So, meine Frage - kurz, die Umwandlung der gesamten Struktur der Daten manuell, gibt es keine Lösung oder Problemumgehung für dieses?
WriteNull()
Methode wird intern aufgerufen, innerhalb der JSON-Serialisierung Prozess, und Sie können nicht bestimmen, welchen Wert Sie sind derzeit serialisieren?Ist es möglich außer Kraft, die WriteValue(Nullable<T>) für den Fall, dass Sie wollen, dass der default-Wert für diesen Typ? Ist die entsprechende Methode aufgerufen, wie für einen int? ist WriteValue(Nullable<int>) genannt, oder kommt es direkt fließen, um WriteNull()? JsonTextWriter
Nach flüchtiger Blick auf den Quellcode Json.Net ich glaube nicht, können Sie dies leicht tun ohne änderung des Quellcodes.
if(value==null)
ist so ziemlich der erste Fall 🙁Oh Mann, ich wünschte, es war ein Weg, zu serialisieren NULL, wenn ein JsonConverterAttribute angegeben wurde auf einem Grundstück. Ich speziell anpassen müssen, um die Ausgabe etwas anderes als "null" auf null festlegbaren Eigenschaften, die in meinem Fall auch zu. Vielleicht können wir das ein feature-request, werde für diese.
InformationsquelleAutor AviD | 2012-01-12
Du musst angemeldet sein, um einen Kommentar abzugeben.
Okay, ich glaube, ich habe zu einer Lösung zu kommen (meine erste Lösung war nicht richtig, aber dann wieder war ich auf der Bahn). Müssen Sie einen speziellen Vertrag, resolver und eine benutzerdefinierte ValueProvider für Nullable-Typen. Bedenken Sie:
Dann getestet habe ich es mit:
Sowie der folgende Fall:
Hoffentlich hilft ein bisschen...
Bearbeiten – Bessere Identifikation der ein
Nullable<>
TypBearbeiten – zusätzliche Unterstützung für Felder sowie Eigenschaften, auch piggy-backing auf der Oberseite des normalen
DynamicValueProvider
zu tun die meisten der Arbeit, mit aktualisierten testIch fand es heraus durch die Verwendung von
GetGenericTypeDefinition() == typeof (Nullable<>)
.Hoppla, ich vergaß, dass Sie auch erforderlich, um die Zeichenfolgen zu übersetzen. Aber es würde umgesetzt werden, mehr oder weniger die gleiche Weise. Sie können eine neue ValueProvider nur für strings, oder ändern Sie die bestehende Signatur anstatt in den generischen Typ, geben Sie einfach in der default-Wert (und bewegen die
Activator.CreateInstance()
eine Ebene nach oben)und ich Stimme zu, es war nicht so intuitiv, wie ich dachte, es wäre, aber das war die einzige Lösung, die ich gefunden habe, der passt in die vorhandene Architektur JSON.NET und erfordert keine änderungen an der Bibliothek selbst.
Ich weiß, wir tun dies nicht, hier aber, nach einem endlosen Tag : Danke !
InformationsquelleAutor James Holmes