首页 > 解决方案 > 如何在尝试添加到列表之前检查属性是否存在

问题描述

我目前正在从 Bungie API Manifest 中提取数据。我成功检索了 .json 文件,我正处于尝试从文件中提取我想要的内容的阶段。

我正在尝试遍历 JSON 文件中的所有条目,并将它们添加到两个activity.Key&activity.displayProperties.name存在的列表中,就像它们在下面的示例中所做的那样

"2693136600": {
    "displayProperties": {
    "description": "\"Grow fat from strength.\"",
    "name": "Leviathan: Normal",
    "icon": "/common/destiny2_content/icons/8b1bfd1c1ce1cab51d23c78235a6e067.png",
    "hasIcon": true
    },

对上述特定 JSON 密钥的完整响应:

"2693136600": { 
"displayProperties": { 
"description": "\"Grow fat from strength.\"", 
"name": "Leviathan: Normal", 
"icon": "/common/destiny2_content/icons/8b1bfd1c1ce1cab51d23c78235a6e067.png", 
"hasIcon": true 
}, 
"originalDisplayProperties": { 
"description": "\"Grow fat from strength.\"", 
"name": "Leviathan", 
"icon": "/img/misc/missing_icon_d2.png", 
"hasIcon": false 
}, 
"selectionScreenDisplayProperties": { 
"description": "Accept an invitation from the Cabal emperor to prove yourself aboard the Leviathan.\n\nRaids are 6 player cooperative activities which test the limits of your skill and teamwork. Master the unique mechanics of each encounter to succeed and earn powerful and exclusive rewards.", 
"name": "Normal", 
"hasIcon": false 
}, 
"releaseIcon": "/img/misc/missing_icon_d2.png", 
"releaseTime": 0, 
"activityLevel": 30, 
"completionUnlockHash": 0, 
"activityLightLevel": 750, 
"destinationHash": 3093898507, 
"placeHash": 330251492, 
"activityTypeHash": 2043403989, 
"tier": 0, 
"pgcrImage": "/img/destiny_content/pgcr/raid_gluttony.jpg", 
"rewards": [ 
{ 
"rewardItems": [ 
{ 
"itemHash": 2127149322, 
"quantity": 0 
} 
] 
}, 
{ 
"rewardItems": [ 
{ 
"itemHash": 669267835, 
"quantity": 0 
} 
] 
} 
], 
"modifiers": [ 
{ 
"activityModifierHash": 2863316929 
}, 
{ 
"activityModifierHash": 3296085675 
}, 
{ 
"activityModifierHash": 871205855 
}, 
{ 
"activityModifierHash": 2770077977 
} 
], 
"isPlaylist": false, 
"challenges": [], 
"optionalUnlockStrings": [], 
"inheritFromFreeRoam": false, 
"suppressOtherRewards": false, 
"playlistItems": [], 
"matchmaking": { 
"isMatchmade": false, 
"minParty": 1, 
"maxParty": 6, 
"maxPlayers": 6, 
"requiresGuardianOath": false 
}, 
"directActivityModeHash": 2043403989, 
"directActivityModeType": 4, 
"activityModeHashes": [ 
2043403989, 
1164760493 
], 
"activityModeTypes": [ 
4, 
7 
], 
"isPvP": false, 
"insertionPoints": [ 
{ 
"phaseHash": 2188993306, 
"unlockHash": 0 
}, 
{ 
"phaseHash": 1431486395, 
"unlockHash": 0 
}, 
{ 
"phaseHash": 3847906370, 
"unlockHash": 0 
}, 
{ 
"phaseHash": 4231923662, 
"unlockHash": 0 
} 
], 
"activityLocationMappings": [], 
"hash": 2693136600, 
"index": 559, 
"redacted": false, 
"blacklisted": false 
},

我的问题是它displayProperties并不总是包含name,所以当这种情况发生时,代码会失败。

我已经尝试了各种方法来做到这一点我无法得到任何工作,因为他们都是catch

我对这个没有深入了解,但它几乎是我正在构建的拼图中的最后一块,所以任何帮助都将不胜感激。

以下是我最近失败的尝试

HttpResponseMessage response = await client.GetAsync("https://bungie.net/common/destiny2_content/json/en/DestinyActivityDefinition-7ab91c74-e8a4-40c7-9f70-16a4354125c0.json");

    if (response.IsSuccessStatusCode)
    {
       try
       {
           dynamic content = response.Content.ReadAsAsync<ExpandoObject>().Result;                   

           foreach (dynamic activity in content)
           {
           //check if .name field exists under displayProperties
               bool exist = activity.displayProperties.name;
               if (exist == false)
               {
               //do nothing
               }
               else
               {
               //add both Key and displayProperties.name to list
                   bungieActivities.Add(new AllBungieActivities() { ActivityHash = activity.Key, ActivityDescription = activity.displayProperties.name });
               }                        
            }  
         }
         catch
         {
           throw new ArgumentException("The member could not be found.");
         }
      }

更新 我没有设法实现以下任何答案并让它工作,但是我有经理让下面的工作但需要相当多的时间才能通过这部分

List<AllBungieActivities> bungieActivities = new List<AllBungieActivities>();

            var response = await client.GetAsync("https://bungie.net/common/destiny2_content/json/en/DestinyActivityDefinition-7ab91c74-e8a4-40c7-9f70-16a4354125c0.json");

            if (response.IsSuccessStatusCode)
            {
                try
                {
                    var content = await response.Content.ReadAsStringAsync();
                    JObject activity = JObject.Parse(content);

                    foreach (JObject refId in activity.Properties().Select(p => p.Value["displayProperties"]))
                    {
                        if (refId.ContainsKey("name"))
                        {
                            bungieActivities.Add(new AllBungieActivities() { ActivityName = (string)refId["name"], ActivityHash = refId.Path.Substring(0, refId.Path.LastIndexOf(".") + 0) });
                        }
                    }

                }
                catch
                {
                    throw new ArgumentException("The member could not be found.");
                }
            }

public class AllBungieActivities
    {
        public string ActivityName;
        public string ActivityHash;
    }

标签: c#json

解决方案


与其反序列化为ExpandoObject,不如创建一个代表您的数据的实际模型并使用它。如果您的 json 中没有必要的键,您的模型将为空,然后您可以进行空检查。

public class Activity
{
    public string Key {get;set;}
    public DisplayProperties DisplayProperties {get;set;}
}

public class DisplayProperties
{
   public string Description {get;set;}
   public string Name {get;set;}
   public string Icon {get;set;}
   public bool HasIcon {get;set;}
}


var activity= response.Content.ReadAsAsync<Activity>().Result;

if(!string.IsNullOrWhiteSpace(activity.Key) && !string.IsNullOrWhiteSpace(activity.DisplayProperties?.Name)
//add to list

推荐阅读