我可以让json.net seiralise每个属性的类型?

时间:2015-03-23 15:10:49

标签: json serializer

我有一个小物件

public class ViewData
{
    public int HistoryId { get; set; }
    public string Address { get; set; }
    public DateTime? FirstOpen { get; set; }       
}

我想把它变成一些看起来像这样的json

  {"SortableFields":[  
      {  
         "name":"HistoryId",
         "type":"int"
      },     
      {  
         "name":"Address",
         "type":"string"
      },
      {  
         "name":"FirstOpen",
         "type":"dateTime"
      }
]}

我最好的方法是什么?它在WebApi中,所以如果我可以挂钩到jsonFormatter,那就太棒了。你看,虽然这些类没有实现任何接口,但我只想对某些类型进行这种处理。如果有帮助,它们都在同一名称空间中。

2 个答案:

答案 0 :(得分:2)

检查我的解决方法(最短的方法)。

public static class JsonDescriptorBuilder
{
    public static string DescriptClass<T>(string header) where T : new()
    {
        var propsObj = typeof (T).GetProperties().Select(pi =>
            new
            {
                name = pi.Name,
                type = pi.PropertyType.Name // or propertyInfo.PropertyType.FullName
            });

        var obj = new
        {
            ___properties = propsObj.ToArray()
        };
        var json = JsonConvert.SerializeObject(obj, Formatting.Indented);
        json = json.Replace("___properties", header);
        return json;
    }
}

使用示例:

internal class Program
{
    private static void Main(string[] args)
    {
        var json = JsonDescriptorBuilder.DescriptClass<ViewData>("SortableFields");
        Console.WriteLine(json);
    }

    public class ViewData
    {
        public int HistoryId { get; set; }
        public string Address { get; set; }
        public DateTime? FirstOpen { get; set; }
    }
}
  

使用Nullable类型的完整版。检查是否更适合您使用   propertyInfo.PropertyType.FullName成立了   propertyInfo.PropertyType.Name

我希望它有所帮助。

答案 1 :(得分:2)

创建JsonConverter custom converter

像这样:

class MyConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteStartObject();
        writer.WritePropertyName("SortableFields");
        writer.WriteStartArray();
        foreach (var prop in value.GetType().GetProperties())
        {
            writer.WriteStartObject();
            writer.WritePropertyName("name");
            writer.WriteValue(prop.Name);
            writer.WritePropertyName("type");
            if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                writer.WriteValue(Nullable.GetUnderlyingType(prop.PropertyType).Name);
            }
            else
            {
                writer.WriteValue(prop.PropertyType.Name);
            }
            writer.WriteEndObject();
        }
        writer.WriteEndArray();
        writer.WriteEndObject();
    }
}

使用此转换器装饰您的对象:

[JsonConverter(typeof(MyConverter))]
public class ViewData
{
    public int HistoryId { get; set; }
    public string Address { get; set; }
    public DateTime? FirstOpen { get; set; }

}

这会导致您的转换器为具有此设置的类触发,但对于那些不具有该设置的类,则会触发正常功能。

编辑:添加代码来处理可空类型。