有没有一种方法可以针对每个对象编写自定义的JsonConverter

3

我有一个类似这样的Json对象:

{"company": "My Company",
"companyStart" : "2015/01/01",
"employee" : 
    { "name" : "john doe",
      "startDate" : 1420434000000 } }

我的JSON对象如下:

public class Company {
    public string company;
    public DateTime companyStart;
    public Employee employee;
}

public class Employee {
    public string name;
    public DateTime startDate;
 }

我的原始代码反序列化的方式如下:

JsonConvert.DeserializeObject<Company>(jsonString);

这段代码可以将 Company.companyStart 转换为 DateTime,但是在转换 Employee.startDate 时无法处理 Long 类型。此 帖子 向我展示了如何创建自定义的 JsonConverter 将 long 转换为 DateTime,但正如您所见,在我的情况下,这将导致将 Company.companyStart 转换为 DateTime 出现问题。因此…… 我正在考虑像这样做:
public class Company : JsonBase {
    ...
}

public class Employee : JsonBase {
    ...
    Employee() { Converter = new CustomDateConverter(); }
}

public class JsonBase {
    private JsonConverter converter;
    [JsonIgnore]
    public JsonConverter Converter => converter ?? (converter = new StandardConverter());
}

JsonBase将包含标准转换器或

在我的代码中,我会将其转换为以下内容:

public T CreateJsonObject<T>() where T : JsonBase {
    JsonBase json = (T) Activator.CreateInstance(typeof (T));
    JsonConvert.DeserializeObject<T>(jsonString, json.Converter);
}

问题在于这种方法无法很好地发挥作用,因为该方法将仅使用最顶层的转换器来进行全部转换,而不是针对每个对象使用转换器。
有没有一种方法可以针对每个对象使用转换器?或者也许有更好的方法来解决这个问题。

哎呀,我在帖子里漏掉了一些词:"JsonBase将包含标准转换器或自定义转换器"。 - Steven
请访问http://json2csharp.com/,并粘贴您的JSON数据,它将为您生成一个C#类。 - MethodMan
1
很酷的工具。但我需要将“startDate”作为DateTime而不是long。 - Steven
如果您使用Newtonsoft的JSON.NET,您可以通过自定义来控制对象的序列化和反序列化:http://blog.maskalik.com/asp-net/json-net-implement-custom-serialization/。您还可以使用内置的属性转换器/属性或编写自己的转换器:http://www.newtonsoft.com/json/help/html/serializationattributes.htm。 - Murray Foxcroft
1个回答

8
如何将您编写的自定义转换器适应于理解这两种格式?
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    if (reader.ValueType == typeof(string))
    {
        return DateTime.Parse((string)reader.Value);
    }
    else if (reader.ValueType == typeof(long))
    {
        return new DateTime(1970, 1, 1).AddMilliseconds((long)reader.Value);
    }
    throw new NotSupportedException();
}

或者,您可以通过使用 JsonConverter 属性将转换器仅应用于模型的特定属性:

public class Employee
{
    public string name;

    [JsonConverter(typeof(MyConverter))]
    public DateTime startDate;
}

这样,您就不需要全局注册转换器,也不会与其他标准日期格式搞混了。

一如既往,我在过度设计我的解决方案。你的JsonConverter属性非常简单。谢谢! - Steven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接