通过JsonConvert和自定义TypeConverter反序列化对象

Max*_*ruk 8 c# json json.net

我有简单的DTO

public class SimpleDto
{
    public int Status { get; set; }
    public long FromDate { get; set; }
    public long ToDate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我有ProxyDto TypeConverterAttribute:

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

这是执行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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我也为DTO提供了简单的Json:

{"Status":3,"FromDate":12345,"ToDate":54321}
Run Code Online (Sandbox Code Playgroud)

当我尝试通过代理反序列化此对象时

var obj = JsonConvert.DeserializeObject<ProxyDto<SimpleDto>>(str);
Run Code Online (Sandbox Code Playgroud)

它以异常失败 'Newtonsoft.Json.JsonSerializationException'

无法将当前JSON对象(例如{"name":"value"})反序列化为类型'Detect_Console_Application_Exit2.ProxyDto`1 [Detect_Console_Application_Exit2.SimpleDto]',因为该类型需要JSON字符串值才能正确反序列化.要修复此错误,请将JSON更改为JSON字符串值或更改反序列化类型,使其成为正常的.NET类型(例如,不是像整数这样的基本类型,而不是像数组或列表那样的集合类型),可以反序列化来自JSON对象.JsonObjectAttribute也可以添加到类型中以强制它从JSON对象反序列化.路径'状态',第1行,第10位.

但如果我的Json逃脱了Json:

"{\"Status\":3,\"FromDate\":12345,\"ToDate\":54321}"
Run Code Online (Sandbox Code Playgroud)

它运作良好.我不明白为什么第一个JSON对象不正确.你能帮助我吗?

更新

这是ToJson方法:

public static class Extension
{
    public static string ToJson(this object val)
    {
        return JsonConvert.SerializeObject(val);
    }
}
Run Code Online (Sandbox Code Playgroud)

Zin*_*nov 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 (!@default.IsCheckAdditionalContentSet())
    @default.CheckAdditionalContent = true;
  using (JsonTextReader jsonTextReader = new JsonTextReader((TextReader) new StringReader(value)))
    return @default.Deserialize((JsonReader) jsonTextReader, type);
}
Run Code Online (Sandbox Code Playgroud)