2016-07-13 8 views
0

einen JSON-String wie folgt Unter der Annahme:eine Transformation auf einem Json DeserializeObject für eine Eigenschaft läuft

string json = '{"string_property":"foo_bar", ... other objects here ...}'; 

ich mich gefragt, ob es einen Weg gibt, um eine Transformation auf dem analysierten Objekt auszuführen, dass anstelle foo_bar zu bekommen, ich werde foo bar erhalten nach der folgenden Methode ausgeführt (kann wirklich alles sein)

public string Transform(string s) { 
    return s.Replace("_"," "); 
} 

ich manuell mein poco nach Deserialisieren verändern kann, aber fragte sich, was ein wäre "sauberer" Ansatz?

+1

Blick auf http://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm –

+0

Versuchen Sie, auch Ihre Eigenschaftsnamen oder nur die Werte zu transformieren? Und wollen Sie die gleiche Transformation für alle Eigenschaften –

+0

Sofern Sie nicht Ihre Eigenschaftsnamen ändern müssen und Sie die gleiche Transformation für alle String-Eigenschaften wollen, wäre der sauberste Ansatz zunächst die Deserialize und dann die Werte aller String-Eigenschaften durch Reflexion zu transformieren. –

Antwort

1

Sie können Ihre string Eigenschaften verwandeln, wie Sie Ihr Wurzelobjekt deserialisieren durch eine custom JsonConverter Verwendung auf allen String-Typ Werte gezielt:

public class ReplacingStringConverter : JsonConverter 
{ 
    readonly string oldValue; 
    readonly string newValue; 

    public ReplacingStringConverter(string oldValue, string newValue) 
    { 
     if (oldValue == null) 
      throw new ArgumentNullException("oldValue"); 
     if (string.IsNullOrEmpty(oldValue)) 
      throw new ArgumentException("string.IsNullOrEmpty(oldValue)"); 
     this.oldValue = oldValue; 
     this.newValue = newValue; 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(string); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.Null) 
      return null; 
     var s = (string)JToken.Load(reader); 
     return s.Replace(oldValue, newValue); 
    } 

    public override bool CanWrite { get { return false; } } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

es dann wie verwenden:

var settings = new JsonSerializerSettings { Converters = new[] { new ReplacingStringConverter("_", "") } }; 
var result = JsonConvert.DeserializeObject<RootObject>(json, settings); 

ist jedoch zu beachten, dass, wenn einzelne String-Eigenschaften haben ihre eigenen Wandler direkt mit [JsonConverter(Type)], diese Wandler werden vor der ReplacingStringConverter in der Converters l verwendet werden ist.

+0

Prost Kumpel, Sie haben mich in die richtige Richtung gezeigt. Ich bin an meine Lösung gebunden. Ich dachte über das Entfernen der Eigenschaften und den Umgang mit "fehlenden", aber es war zu viel Aufwand für meine Bedürfnisse. – Noctis

0

Ich habe Sie folgendermaßen vorgehen endete:

Erstellen Sie zunächst einen Konverter, der nur liest und alle es tut, ist URL die Zeichenfolge entschlüsseln.

public class UrlDecoderConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(string); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.Null) 
      return null; 
     var s = (string)JToken.Load(reader); 
     return HttpUtility.UrlDecode(s); 
    } 

    public override bool CanWrite => false; 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Dann einfach die folgenden der POCO-Eigenschaften hinzuzufügen, die decodiert werden müssen:

[JsonConverter(typeof(UrlDecoderConverter))] 
public string url { get; set; }