FreshService API с именами свойств Restsharp и Dynamic

Я пытаюсь использовать FreshService API для активов, и получение списка активов возвращает JSON, как показано ниже. Обратите внимание, что свойства внутри "levelfield_values" имеют идентификатор, добавленный в конце имени их свойства.

Я пытаюсь получить «license_expiry_date» для всех активов, но у меня возникают проблемы с преобразованием в объекты для извлечения этого поля, поскольку имя меняется с каждым элементом. Какие-либо предложения?

{"config_item": {"agent_id": 215,
"asset_tag": batch_2017,
"assigned_on": "2014-07-18T03:54:18+05:30",
"ci_type_id": 3,
"created_at": "2014-07-25T14:25:04+05:30",
"deleted": false,
"department_id": 4,
"depreciation_id": null,
"description": null,
"disabled": false,
"display_id": 113,
"expiry_notified": false,
"id": 113,
"impact": 3,
"location_id": 21,
"name": "windows 7",
"salvage": null,
"trashed": false,
"updated_at": "2014-07-25T14:25:04+05:30",
"user_id": 214,
"department_name": "Finance",
"used_by": "Rachel",
"business_impact": "Medium",
"agent_name": "Andrea",
"levelfield_values": {
  "product_3": 100,
  "vendor_3": 43,
  "cost_3": 4000,
  "license_validity_3": 24,
  "installation_date_3": "2014-07-25T14:25:04+05:30",
  "license_expiry_date_3": "2016-07-25T00:00:00+05:30",
  "license_key_3": "234_423_543_534",
  "version_3": 2,
  "license_type_3": "commercial",
  "installed_machine_3": "Andrea’s computer",
  "installation_path_3": null,
  "last_audit_date_3": "2014-07-25T14:25:04+05:30"
},
"ci_type_name": "Software",
"product_name": "windows_os",
"vendor_name": "micosoft",
"state_name": null,
"location_name": "America"  } }
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
168
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы могли бы сделать что-то вроде этого

JsonConvert.DeserializeObject<JObject>(jsonString)["config_item"]["levelfield_values"]
    .ToObject<JObject>()
    .Properties()
    .FirstOrDefault(x => x.Name.ToLower().Contains("license_validity"));

в основном вы;

  • перейти в config_item
  • перейти в levelfield_values
  • получить все свойства навигационного объекта (levelfield_values)
  • найти свойство с таким именем, как license_validity
Ответ принят как подходящий

Этот пример Json ужасен и неверен, но... вот как я сделаю сериализацию бесшовной.

  • levelfield_values для определения как объект Expando
  • определение класса для levelfield_values ​​чистым (без идентификатора в свойствах)
  • Добавьте регенеративные свойства между Expando к определенному свойству класса и наоборот

Я использовал специальную пасту Visual Studio для первоначального написания класса.

Пример или рабочий пример:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var example = new Config
            {
                config_item = new Config_Item
                {
                    LevelfieldValuesParshed = new CleanLevelfield_Values
                    {
                        Id = 2,
                        product = 1232
                    }
                }
            };
            var serialized = JsonConvert.SerializeObject(example); // should have "product_2" : 2 inside
            // VOILA deserialization with property parsing in a clean object
            var deserialzed = JsonConvert.DeserializeObject<Config>(serialized);
            if (example.config_item.LevelfieldValuesParshed.Id != deserialzed.config_item.LevelfieldValuesParshed.Id || 
                example.config_item.LevelfieldValuesParshed.product != deserialzed.config_item.LevelfieldValuesParshed.product)
            {
                throw new Exception("Impossible to happen!!!");
            }
        }
    }

    public class Config
    {
        public Config_Item config_item { get; set; }
    }

    public class Config_Item
    {
        public int agent_id { get; set; }
        public string asset_tag { get; set; }
        public DateTime assigned_on { get; set; }
        public int ci_type_id { get; set; }
        public DateTime created_at { get; set; }
        public bool deleted { get; set; }
        public int department_id { get; set; }
        public object depreciation_id { get; set; }
        public object description { get; set; }
        public bool disabled { get; set; }
        public int display_id { get; set; }
        public bool expiry_notified { get; set; }
        public int id { get; set; }
        public int impact { get; set; }
        public int location_id { get; set; }
        public string name { get; set; }
        public object salvage { get; set; }
        public bool trashed { get; set; }
        public DateTime updated_at { get; set; }
        public int user_id { get; set; }
        public string department_name { get; set; }
        public string used_by { get; set; }
        public string business_impact { get; set; }
        public string agent_name { get; set; }

        // Regenerative property with backing filed => _levelfieldValuesParshed
        [JsonIgnore]  // Ignore property at serialization
        public CleanLevelfield_Values LevelfieldValuesParshed
        {
            get
            {
                if (_levelfieldValuesParshed == null)
                {
                    if (_levelfield_values != null) // if null everything is null
                    {
                        var propsByName = (IDictionary<string, object>)_levelfield_values; // Expando Object to dictionary
                        var product = propsByName.Keys.FirstOrDefault(x => x.StartsWith("product_", StringComparison.InvariantCultureIgnoreCase)); // user first to fail if not found, it can be smarter but it works
                        if (!string.IsNullOrEmpty(product))// hurray we know the id
                        {
                            if (int.TryParse(product.Replace("product_", ""), out int id)) // C# 7
                            {
                                // Cleaner code can be written (generic method to set get object props with reflection)
                                _levelfieldValuesParshed = new CleanLevelfield_Values
                                {
                                    Id = id
                                };
                                _levelfieldValuesParshed.product = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"product_{id}", StringComparison.InvariantCultureIgnoreCase)))
                                    ? Convert.ToInt32(propsByName.First(x => x.Key.Equals($"product_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : 0;
                                _levelfieldValuesParshed.vendor = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"vendor_{id}", StringComparison.InvariantCultureIgnoreCase)))
                                ? Convert.ToInt32(propsByName.First(x => x.Key.Equals($"vendor_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : 0;
                                _levelfieldValuesParshed.cost = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"cost_{id}", StringComparison.InvariantCultureIgnoreCase)))
                                    ? Convert.ToInt32(propsByName.First(x => x.Key.Equals($"cost_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : 0;
                                _levelfieldValuesParshed.license_validity = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"license_validity_{id}", StringComparison.InvariantCultureIgnoreCase)))
                                    ? Convert.ToInt32(propsByName.First(x => x.Key.Equals($"license_validity_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : 0;
                                _levelfieldValuesParshed.installation_date = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"installation_date_{id}", StringComparison.InvariantCultureIgnoreCase)))
                                    ? Convert.ToDateTime(propsByName.First(x => x.Key.Equals($"installation_date_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : DateTime.MinValue;
                                _levelfieldValuesParshed.license_expiry_date = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"license_expiry_date_{id}", StringComparison.InvariantCultureIgnoreCase)))
                                    ? Convert.ToDateTime(propsByName.First(x => x.Key.Equals($"license_expiry_date_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : DateTime.MinValue;
                                _levelfieldValuesParshed.license_key = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"license_key_{id}", StringComparison.InvariantCultureIgnoreCase)))
                                    ? Convert.ToString(propsByName.First(x => x.Key.Equals($"license_key_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : string.Empty;
                                _levelfieldValuesParshed.version = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"version_{id}", StringComparison.InvariantCultureIgnoreCase)))
                                    ? Convert.ToInt32(propsByName.First(x => x.Key.Equals($"version_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : 0;
                                _levelfieldValuesParshed.license_type = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"license_type_{id}", StringComparison.InvariantCultureIgnoreCase)))
                                    ? Convert.ToString(propsByName.First(x => x.Key.Equals($"license_type_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : string.Empty;
                                _levelfieldValuesParshed.installed_machine = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"installed_machine_{id}", StringComparison.InvariantCultureIgnoreCase)))
                                    ? Convert.ToString(propsByName.First(x => x.Key.Equals($"installed_machine_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : string.Empty;
                                _levelfieldValuesParshed.installation_path = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"installation_path_{id}", StringComparison.InvariantCultureIgnoreCase)))
                                    ? propsByName.First(x => x.Key.Equals($"installation_path_{id}", StringComparison.InvariantCultureIgnoreCase)).Value : new object();
                                _levelfieldValuesParshed.last_audit_date = !string.IsNullOrEmpty(propsByName.Keys.FirstOrDefault(x => x.Equals($"last_audit_date_{id}", StringComparison.InvariantCultureIgnoreCase)))
                                    ? Convert.ToDateTime(propsByName.First(x => x.Key.Equals($"last_audit_date_{id}", StringComparison.InvariantCultureIgnoreCase)).Value) : DateTime.MinValue;
                            }
                        }
                    }
                }
                return _levelfieldValuesParshed;
            }
            set
            {
                _levelfieldValuesParshed = value;
                _levelfield_values = null;
            }
        }
        private CleanLevelfield_Values _levelfieldValuesParshed;

        // Regenerative Expando property with backing field => _levelfield_values
        public System.Dynamic.ExpandoObject levelfield_values
        {
            get
            {
                if (_levelfieldValuesParshed != null)
                {
                    _levelfield_values = new ExpandoObject();
                    // Cleaner code can be written with a foreach (generic method to set get object props with reflection)
                    var keValuesPairs = (IDictionary<string, object>)_levelfield_values;
                    keValuesPairs.Add($"product_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.product);
                    keValuesPairs.Add($"vendor_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.vendor);
                    keValuesPairs.Add($"cost_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.cost);
                    keValuesPairs.Add($"license_validity_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.license_validity);
                    keValuesPairs.Add($"installation_date_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.installation_date);
                    keValuesPairs.Add($"license_expiry_date_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.license_expiry_date);
                    keValuesPairs.Add($"license_key_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.license_key);
                    keValuesPairs.Add($"version_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.version);
                    keValuesPairs.Add($"license_type_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.license_type);
                    keValuesPairs.Add($"installed_machine_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.installed_machine);
                    keValuesPairs.Add($"installation_path_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.installation_path);
                    keValuesPairs.Add($"last_audit_date_{_levelfieldValuesParshed.Id}", _levelfieldValuesParshed.last_audit_date);
                    return _levelfield_values;
                }
                return null;
            }
            set
            {
                _levelfield_values = value;
                _levelfieldValuesParshed = null; // remove cleaned object, it will regenerated itself when opened
            }
        }
        private ExpandoObject _levelfield_values;
        public string ci_type_name { get; set; }
        public string product_name { get; set; }
        public string vendor_name { get; set; }
        public object state_name { get; set; }
        public string location_name { get; set; }
    }

    public class CleanLevelfield_Values
    {
        public int Id { get; set; }
        public int product { get; set; }
        public int vendor { get; set; }
        public int cost { get; set; }
        public int license_validity { get; set; }
        public DateTime installation_date { get; set; }
        public DateTime license_expiry_date { get; set; }
        public string license_key { get; set; }
        public int version { get; set; }
        public string license_type { get; set; }
        public string installed_machine { get; set; }
        public object installation_path { get; set; }
        public DateTime last_audit_date { get; set; }
    }

}

Другие вопросы по теме