json.net — не удается разобрать вложенные объекты

#c# #json #json.net

#c# #json #json.net

Вопрос:

Я пытаюсь создать объект из строки json. Сложность в том, что для части json я не буду знать количество или имя ключей.

Вот что я пробовал до сих пор.

json — файл:

 {
   "browser":"Chrome",
   "call":{
      "addEventListener":199,
      "appendChild":34,
      "createElement":8,
      "getAttribute":2170,
   },
   "get":{
      "linkColor":1,
      "vlinkColor":1
   },
   "session":"3211658131",
   "tmStmp":"21316503513854"
}
 

Объект:

 public class ClearCoatDataObject
    {
        public string browser { get; set; }
        public string session { get; set; }
        public string url { get; set; }
        public string tmStmp { get; set; }
        public string _id { get; set; }
        public ObjectPropertiesDictionary create { get; set; }
        public ObjectPropertiesDictionary call { get; set; }
        public ObjectPropertiesDictionary get { get; set; }
        public ObjectPropertiesDictionary set { get; set; } 


        public static ClearCoatDataObject FromJson(string json)
        {
            return JsonConvert.DeserializeObject<ClearCoatDataObject>(json);
        }
        public String ToJson()
        {
            return JsonConvert.SerializeObject(this);
        }

        public ActionObjectsDictionary GetActions()
        {
            ActionObjectsDictionary actionTypes = new ActionObjectsDictionary();

            actionTypes.Add("create", create);
            actionTypes.Add("call", call);
            actionTypes.Add("get", get);
            actionTypes.Add("set", set);

            return actionTypes;
        }

        public ClearcoatDataItemCollection Flatten()
        {

            ClearcoatDataItemCollection retCollection = new ClearcoatDataItemCollection();

            // foreach constr in action
            ActionObjectsDictionary actionTypes = GetActions();

            foreach (KeyValuePair<string, ObjectPropertiesDictionary> actionType in actionTypes)
            {
                ObjectPropertiesDictionary objectProperties = actionType.Value;
                foreach (KeyValuePair<string, PropertyCountsDictionary> objectProperty in objectProperties)
                {
                    PropertyCountsDictionary propertyCounts = objectProperty.Value;
                    foreach (KeyValuePair<string, int> propertyCount in propertyCounts)
                    {
                        ClearCoatDataItem ccdi = new ClearCoatDataItem(this.session, this.url, actionType.Key, objectProperty.Key, propertyCount.Key, propertyCount.Value);
                        retCollection.Add(ccdi);
                    }
                }
            }
            return retCollection;

        }
    }

    // Dictionary Classes to hold:
    //      actions (
    //      
    public class PropertyCountsDictionary : Dictionary<string, int> { }
    public class ObjectPropertiesDictionary : Dictionary<string, PropertyCountsDictionary> { }
    public class ActionObjectsDictionary : Dictionary<string, ObjectPropertiesDictionary> { }
 

Когда я запускаю код (это для веб-сервиса), я получаю сообщение об ошибке:
Ошибка при синтаксическом анализе Json. Newtonsoft.Json.Исключение JsonSerializationException: ошибка преобразования значения 1 в тип ‘PropertyCountsDictionary’. Путь ‘get.vlinkColor’, строка 1, позиция 152. —> Система.ArgumentException: Не удалось выполнить приведение или преобразование из System.Int64 в PropertyCountsDictionary.

Спасибо за любую помощь, которую вы можете предоставить.

Ответ №1:

Похоже, у вас есть дополнительный словарь, который вам не нужен. Это то, что вам нужно?

 public class Program
{
    private static void Main(string[] args)
    {
        var json = @"{
           ""browser"":""Chrome"",
           ""call"":{
              ""addEventListener"":199,
              ""appendChild"":34,
              ""createElement"":8,
              ""getAttribute"":2170,
           },
           ""get"":{
              ""linkColor"":1,
              ""vlinkColor"":1
           },
           ""session"":""3211658131"",
           ""tmStmp"":""21316503513854""
        }";

        var clearCoatDataObject = ClearCoatDataObject.FromJson(json);
        foreach (var ccdi in clearCoatDataObject.Flatten())
        {
            Console.WriteLine(ccdi.ToJson());
        }
    }

    public class ClearCoatDataObject
    {
        public string browser { get; set; }
        public string session { get; set; }
        public string url { get; set; }
        public string tmStmp { get; set; }
        public string _id { get; set; }
        public PropertyDictionary create { get; set; }
        public PropertyDictionary call { get; set; }
        public PropertyDictionary get { get; set; }
        public PropertyDictionary set { get; set; }


        public static ClearCoatDataObject FromJson(string json)
        {
            return JsonConvert.DeserializeObject<ClearCoatDataObject>(json);
        }
        public String ToJson()
        {
            return JsonConvert.SerializeObject(this);
        }

        public ActionDictionary GetActions()
        {
            ActionDictionary actionTypes = new ActionDictionary();

            actionTypes.Add("create", create);
            actionTypes.Add("call", call);
            actionTypes.Add("get", get);
            actionTypes.Add("set", set);

            return actionTypes;
        }

        public ClearcoatDataItemCollection Flatten()
        {

            ClearcoatDataItemCollection retCollection = new ClearcoatDataItemCollection();

            // foreach constr in action
            ActionDictionary actionTypes = GetActions();

            foreach (var actionType in actionTypes)
            {
                PropertyDictionary property = actionType.Value;
                if (property != null)
                {
                    foreach (KeyValuePair<string, int> propertyCount in property)
                    {
                        ClearCoatDataItem ccdi = new ClearCoatDataItem(this.session, this.url, actionType.Key, propertyCount.Key, propertyCount.Value);
                        retCollection.Add(ccdi);
                    }
                }
            }
            return retCollection;

        }
    }

    // Dictionary Classes to hold:
    //      actions (
    //      
    public class PropertyDictionary : Dictionary<string, int> { }
    public class ActionDictionary : Dictionary<string, PropertyDictionary> { }
}
 

Комментарии:

1. Спасибо, tmack. Глупая ошибка. Кроме того, мне нужно было изменить словарь с <string, int> на <string, string> . Значение int возвращалось как null.