【问题标题】:Deserialize object via JsonConvert and custom TypeConverter [duplicate]通过 JsonConvert 和自定义 TypeConverter 反序列化对象 [重复]
【发布时间】:2015-12-04 13:16:56
【问题描述】:

我有简单的 DTO

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

我有 TypeConverterAttribute 的 ProxyDto:

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

我还有用于 DTO 的简单 Json:

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

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

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

失败并出现异常'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}"

效果很好。我不明白为什么第一个 JSON 对象不正确。你能帮帮我吗?

更新

这里是ToJson方法:

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

【问题讨论】:

  • @CodeCaster 我已经更新了我的问题。
  • 出于好奇,您为什么还要在您的ProxyDto 中使用TypeConverter?如果您的目标是将代理转换为 JSON 或从 JSON 转换,您可以在代理上调用 JsonConvert.SerializeObject() / JsonConvert.DeserializeObject() 并且在没有转换器的情况下它应该可以正常工作。转换器强制它被双重序列化,这就是你最终得到转义 JSON 的原因。
  • 我尝试从 WCF 服务器中的 GET 方法解析查询字符串,因此它必须具有 TypeConvertAttribute。但是我做不到,因为 JsonConverter 也使用了这个属性,我创建了代理对象来封装SimleDto
  • Json.NET 看到您的 ProxyDto&lt;T&gt; 有一个 TypeConverter 并使用它来将其从字符串转换为字符串。见Serialization Guide。为避免这种情况,请使用Newtonsoft.JSON cannot convert model with TypeConverter attribute 中的解决方案。
  • @dbc 这似乎是工作。谢谢。

标签: c# json json.net


【解决方案1】:

正如@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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-24
    • 1970-01-01
    相关资源
    最近更新 更多