2016-02-05 2 views
2

Как генерировать метаданные JSON класса.Как получить метаданные класса в строку JSON

например.

C# Классы

public class Product 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public bool IsActive { get; set; } 
    public Description Description { get; set; } 
} 

public class Description 
{ 
    public string Content { get; set; } 
    public string ShortContent { get; set; } 
} 

JSON

[ 
    { 
     "PropertyName" : "Id", 
     "Type" : "Int", 
     "IsPrimitive" : true 
    }, 
    { 
     "PropertyName" : "Name", 
     "Type" : "string", 
     "IsPrimitive" : true 
    }, 
    { 
     "PropertyName" : "IsActive", 
     "Type" : "bool", 
     "IsPrimitive" : true 
    }, 
    { 
     "PropertyName" : "Description", 
     "Type" : "Description", 
     "IsPrimitive" : false 
     "Properties" : { 
      { 
       "PropertyName" : "Content", 
       "Type" : "string", 
       "IsPrimitive" : true 
      }, 
      { 
       "PropertyName" : "ShortContent", 
       "Type" : "string", 
       "IsPrimitive" : true 
      } 
     } 
    }, 
] 
+0

Таким образом, вы не хотите, чтобы значение, только описание типа? – Thomas

+0

@Thomas Нет, мне просто нужна информация о члене класса, чтобы я мог передать его потребителю –

+0

см. Мое сообщение, это должно делать то, что вы хотите. – Thomas

ответ

3

Если определить класс, который будет отображать ваш JSon Модель:

public class PropertyDescription 
{ 
    public string PropertyName { get; set; } 

    public string Type { get; set; } 

    public bool IsPrimitive { get; set; } 

    public IEnumerable<PropertyDescription> Properties { get; set; } 
} 

А потом просто создать функцию, которая для чтения свойства вашего объекта рекурсивно:

public static List<PropertyDescription> ReadObject(Type type) 
{ 
    var propertyDescriptions = new List<PropertyDescription>(); 
    foreach (var propertyInfo in type.GetProperties()) 
    { 
     var propertyDescription = new PropertyDescription 
     { 
      PropertyName = propertyInfo.Name, 
      Type = propertyInfo.PropertyType.Name 
     }; 

     if (!propertyDescription.IsPrimitive 
      // String is not a primitive type 
      && propertyInfo.PropertyType != typeof (string)) 
     { 
      propertyDescription.IsPrimitive = false; 
      propertyDescription.Properties = ReadObject(propertyInfo.PropertyType); 
     } 
     else 
     { 
      propertyDescription.IsPrimitive = true;    
     } 
     propertyDescriptions.Add(propertyDescription); 
    } 

    return propertyDescriptions; 
} 

Вы можете использовать Json.Net сериализовать результат этой функции:

var result = ReadObject(typeof(Product)); 
var json = JsonConvert.SerializeObject(result); 

EDIT: Linq решение на основе @AmitKumarGhosh ответ:

public static IEnumerable<object> ReadType(Type type) 
{ 
    return type.GetProperties().Select(a => new 
    { 
     PropertyName = a.Name, 
     Type = a.PropertyType.Name, 
     IsPrimitive = a.PropertyType.IsPrimitive && a.PropertyType != typeof (string), 
     Properties = (a.PropertyType.IsPrimitive && a.PropertyType != typeof(string)) ? null : ReadType(a.PropertyType) 
    }).ToList(); 
} 

... 

var result = ReadType(typeof(Product)); 
json = JsonConvert.SerializeObject(result); 
+0

Отличное решение! Но вместо передачи объекта я хочу передать Type в функцию ReadObject. как 'ReadObject (Product.GetType()) –

+0

Я отредактировал свой ответ, чтобы передать тип вместо значения. Можете ли вы пометить вопрос как ответ, если вам это подходит? – Thomas

+0

Работает отлично. Большое вам спасибо: –

2

Попробуйте это, концепция получить все элементы из объекта в словаре. Имя и значение поля. Для каждого свойства создайте дополнительные элементы (используя Reflection) в словаре, например Type, IsPrimitive и т. Д. Вы можете использовать рекурсию для перехода свойств throw, а затем сериализовать этот словарь в JSON.

Пример здесь:

Appending to JSON object using JSON.net

Пример этого:

 var serialize = new Newtonsoft.Json.JsonSerializer(); 

     var dict = GetDic(new Description()); 

     serialize.Serialize(sr, dict); 

И реализация GetDcit:

private List<Dictionary<string, string>> GetDic(object obj) 
    { 
     var result= new List<Dictionary<string, string>>(); 

     foreach (var r in obj.GetType().GetProperties()) 
     { 
      result.Add(new Dictionary<string, string> 
      { 
       ["PropertyName"] = r.Name, 
       ["Type"] = r.PropertyType.Name, 
       ["IsPrimitive"] = r.GetType().IsPrimitive.ToString(), 
      }); 
     } 

     return result; 
    } 
+2

Упрощенный для имени вашей функции! GetDic .... – Thomas

+0

Зачем писать Json в файле? – Thomas

+1

Без причины. Это только копия пасты из моего проекта. Я обновляю свой ответ. Спасибо. –

2

Одно возможное решение -

static void Main(string[] args) 
    { 
     var o = typeof(Product).GetProperties().Select(a => 
      { 
       if (a.PropertyType != null && (a.PropertyType.IsPrimitive || a.PropertyType == typeof(string))) 
       { 
        return MapType(a); 
       } 
       else 
       { 
        dynamic p = null; 
        var t = MapType(a); 
        var props = a.PropertyType.GetProperties(); 
        if (props != null) 
        { p = new { t, Properties = props.Select(MapType).ToList() }; } 

        return new { p.t.PropertyName, p.t.Type, p.t.IsPrimitive, p.Properties }; 
       } 

      }).ToList(); 

     var jsonString = JsonConvert.SerializeObject(o); 
    } 

    static dynamic MapType(PropertyInfo a) 
    { 
     return new 
     { 
      PropertyName = a.Name, 
      Type = a.PropertyType.Name, 
      IsPrimitive = a.PropertyType != null && a.PropertyType.IsPrimitive 
     }; 
    } 
+0

работает с этой иерархией и предоставляет возможное решение. –

Смежные вопросы