2015-12-04 2 views
8

У меня есть простой DTODeserialize через JsonConvert и пользовательские TypeConverter

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

И я ProxyDto с TypeConverterAttribute:

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

Вот реализация 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); 
    } 
} 

Также У меня есть простой Json для DTO:

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

Когда я пытаюсь десериализации этого объекта через прокси

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

он терпит неудачу с Exception 'Newtonsoft.Json.JsonSerializationException'

Не может десериализации объекта тока JSON (например, {"name": "value"}) в тип 'Detect_Console_Application_Exit2.ProxyDto`1 [Detect_Console_Application_Exit2.SimpleDto]', потому что для этого требуется, чтобы строковое значение JSON десериализовалось правильно. Чтобы исправить эту ошибку, либо измените JSON на строковое значение JSON, либо измените десериализованный тип, чтобы он был обычным типом .NET (например, не примитивным типом типа integer, а не типом коллекции, подобным массиву или списку), который может быть десериализован из объекта JSON. JsonObjectAttribute также можно добавить к типу, чтобы заставить его десериализовать объект JSON. Путь 'Статус', строка 1, позиция 10.

Но если мой Json имеет спасаясь JSon:

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

он работает хорошо. Я не понимаю, почему первый объект JSON неверен. Вы можете мне помочь?

Update

Вот ToJson метод:

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

@CodeCaster Я обновил свой вопрос. –

+0

@maxim 'SimpleDto obj = JsonConvert.DeserializeObject (jsonstring);' Как говорится в сообщении об ошибке, вы не можете десериализовать один объект в коллекции (ProxyDto <>). – Webruster

+0

@Webruster 'ProxyDto ' не является коллекцией. – CodeCaster

ответ

0

Как @dbc сказал, что это просто конвертировать объекты, которые наследуют от JsonConverter, ниже код, который они используют, сериализатору по умолчанию основывается на параметр преобразователей. Вы должны наследовать от JsonConverter вместо 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); 
} 
Смежные вопросы