2015-12-04 16 views
8

devo semplice DTODeserialize via JsonConvert e personalizzato TypeConverter

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

E devo ProxyDto con TypeConverterAttribute:

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

Ecco l'attuazione di SimpleConvert:

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); 
    } 
} 

anche Ho un semplice JSON per DTO:

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

Quando provo a deserializzare questo oggetto tramite delega

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

viene a mancare con eccezione 'Newtonsoft.Json.JsonSerializationException'

Impossibile deserializzare l'oggetto JSON corrente (per esempio {"nome": "valore"}) nel tipo "Detect_Console_Application_Exit2.ProxyDto`1 [Detect_Console_Application_Exit2.SimpleDto] 'perché il tipo richiede un valore di stringa JSON per deserializzare correttamente. Per correggere questo errore, modificare il JSON in un valore stringa JSON o modificare il tipo deserializzato in modo che sia un normale tipo .NET (ad esempio non un tipo primitivo come intero, non un tipo di raccolta come un array o elenco) che può essere deserializzato da un oggetto JSON. JSONObjectAttribute può anche essere aggiunto al tipo per forzarlo a deserializzare da un oggetto JSON. Path 'Stato', la linea 1, la posizione 10.

Ma se la mia JSON è fuga JSON:

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

funziona bene. Non capisco perché il primo oggetto JSON non sia corretto. Mi potete aiutare?

Aggiornamento

Ecco ToJson metodo:

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

@CodeCaster Ho aggiornato la mia domanda. –

+0

@maxim 'SimpleDto obj = JsonConvert.DeserializeObject (jsonstring);' Come il messaggio di errore indica che non è possibile deserializzare un singolo oggetto in una raccolta (ProxyDto <>). – Webruster

+0

@Webruster 'ProxyDto ' non è una raccolta. – CodeCaster

risposta

0

Come @dbc ha detto che solo convertire gli oggetti che ereditano da JsonConverter, sotto è il codice che usano, il serializzatore predefinito si basa su il parametro convertitori. Si dovrebbe ereditare da JsonConverter invece di TypeConverter

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); 
}