带有Restsharp和Dynamic属性名称的FreshService API

时间:2019-01-25 02:17:40

标签: c# .net json restsharp

我正在尝试对资产使用FreshService API,获取资产列表将返回JSON,如下所示。请注意,“ levelfield_values”内部的属性的ID附加在其属性名称的末尾。

我正在尝试为所有资产提取“ 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"  } }

2 个答案:

答案 0 :(得分: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的属性

答案 1 :(得分:1)

Json的示例很糟糕而且不正确,但是..这是使序列化无缝化的方式。

  • levelfield_values 定义为Expando对象
  • 为levelfield_values定义一个干净的类(属性中没有id)
  • 将Expando之间的再生属性添加到已定义的类属性中,反之亦然

我最初使用Visual Studio粘贴特殊语言来编写课程。

示例或fiddle

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; }
    }

}