2015-12-04 1 views
8

Ich habe einfach DTODeserialize Objekt über JsonConvert und benutzerdefinierten Typeconverter

public class SimpleDto 
{ 
    public int Status { get; set; } 
    public long FromDate { get; set; } 
    public long ToDate { get; set; } 
} 

Und ich habe ProxyDto mit TypeConverterAttribute:

[TypeConverter(typeof(SimpleConvert<SimpleDto>))] 
public class ProxyDto<T> 
{ 
    public T Object { get; set; } 
} 

Hier ist die Implementierung von SimpleConvert: Auch

public class SimpleConvert<T> : TypeConverter 
{ 
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 
    { 
     return sourceType == typeof(string) || 
       base.CanConvertFrom(context, sourceType); 
    } 

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 
    { 
     var strValue = value as string; 
     return strValue != null 
      ? new ProxyDto<T>{ Object = JsonConvert.DeserializeObject<T>(strValue)} 
      : base.ConvertFrom(context, culture, value); 
    } 

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 
    { 
     var val = value as ProxyDto<T>; 
     return destinationType == typeof(string) && val != null ? val.Object.ToJson() : base.ConvertTo(context, culture, value, destinationType); 
    } 
} 

Ich habe einfach Json für DTO:

{"Status":3,"FromDate":12345,"ToDate":54321} 

Wenn ich versuche, über Proxy dieses Objekt deserialisieren

var obj = JsonConvert.DeserializeObject<ProxyDto<SimpleDto>>(str); 

es fällt mit Exception 'Newtonsoft.Json.JsonSerializationException'

kann nicht die aktuelle JSON-Objekt deserialisieren (z {"name": "value"}) in den Typ 'Detect_Console_Application_Exit2.ProxyDto`1 [Detect_Console_Application_Exit2.SimpleDto]', da der Typ die korrekte Deserialisierung eines JSON-Zeichenfolgenwerts erfordert. Um diesen Fehler zu beheben, ändern Sie den JSON entweder in einen JSON-Zeichenfolgenwert oder ändern Sie den deserialisierten Typ so, dass es ein normaler .NET-Typ ist (z. B. kein primitiver Typ wie ganze Zahlen, kein Sammlertyp wie Array oder Liste) aus einem JSON-Objekt deserialisiert. JsonObjectAttribute kann auch zum Typ hinzugefügt werden, um die Deserialisierung von einem JSON-Objekt zu erzwingen. Pfad 'Status', Zeile 1, Position 10.

Aber wenn meine Json hat Json zu entkommen:

"{\"Status\":3,\"FromDate\":12345,\"ToDate\":54321}" 

es gut funktioniert. Ich verstehe nicht, warum das erste JSON-Objekt nicht korrekt ist. Kannst du mir helfen?

aktualisieren

Hier ToJson Methode ist:

public static class Extension 
{ 
    public static string ToJson(this object val) 
    { 
     return JsonConvert.SerializeObject(val); 
    } 
} 
+0

@CodeCaster Ich habe meine Frage aktualisiert. –

+0

@maxim 'SimpleDto obj = JsonConvert.DeserializeObject (jsonstring);' Die Fehlermeldung besagt, dass Sie ein einzelnes Objekt nicht in eine Auflistung deserialisieren können (ProxyDto <>). – Webruster

+0

@Webruuster 'ProxyDto ' ist keine Sammlung. – CodeCaster

Antwort

0

Wie @dbc sagte es nur Objekte konvertieren, die von JsonConverter erben, unten ist der Code, die sie verwenden, wird die Standard-Serializer basierend auf der Konverter Parameter. Sie sollten von JsonConverter anstelle von TypeConverter

erben
public static object DeserializeObject(string value, Type type, params JsonConverter[] converters) 
{ 
    JsonSerializerSettings serializerSettings; 
    if (converters == null || converters.Length <= 0) 
    serializerSettings = (JsonSerializerSettings) null; 
    else 
    serializerSettings = new JsonSerializerSettings() 
    { 
     Converters = (IList<JsonConverter>) converters 
    }; 
    JsonSerializerSettings settings = serializerSettings; 
    return JsonConvert.DeserializeObject(value, type, settings); 
} 

public static object DeserializeObject(string value, Type type, JsonSerializerSettings settings) 
{ 
    ValidationUtils.ArgumentNotNull((object) value, "value"); 
    JsonSerializer @default = JsonSerializer.CreateDefault(settings); 
    if ([email protected]()) 
    @default.CheckAdditionalContent = true; 
    using (JsonTextReader jsonTextReader = new JsonTextReader((TextReader) new StringReader(value))) 
    return @default.Deserialize((JsonReader) jsonTextReader, type); 
}