Reputation: 107
I have a JSON file that has a property called craftingrequirements. This property can be an object or an array, what is the best way to process data in such a case?
Currently I have set the type to object for the property because otherwise there would be an error.
"weapon": [
{
"@uniquename": "T3_2H_QUARTERSTAFF",
"craftingrequirements": [
{
"@silver": "0",
"@time": "5",
"@craftingfocus": "16085",
},
{
"@silver": "0",
"@time": "5",
"@craftingfocus": "16085"
}
]
},
{
"@uniquename": "T6_2H_QUARTERSTAFF_AVALON",
"craftingrequirements": {
"@silver": "0",
"@time": "1",
"@craftingfocus": "980"
}
}
]
That didn't work either..
var craftingRequirement = equipmentItem.CraftingRequirements as CraftingRequirements;
if (craftingRequirement == null)
{
var craftingRequirements = equipmentItem.CraftingRequirements as List<CraftingRequirements>;
}
if (equipmentItem.CraftingRequirements is CraftingRequirements)
{
}
else if (equipmentItem.CraftingRequirements is List<CraftingRequirements>)
{
}
I work with .net / C# and haven't found a good solution yet.
Upvotes: 2
Views: 2066
Reputation: 107
Only for those who care. There were other nested objects and arrays.
This is my current solution that works.
Maybe someone can do something with it, then just needs to be adjusted.
public class CraftingRequirementsToCraftingRequirementsList : JsonConverter<List<CraftingRequirements>>
{
public override List<CraftingRequirements> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject && reader.TokenType != JsonTokenType.StartArray)
{
throw new JsonException("JSON payload expected to start with StartObject or StartArray token.");
}
var craftingRequirements = new List<CraftingRequirements>();
try
{
craftingRequirements = reader.TokenType switch
{
JsonTokenType.StartArray => SetCraftingRequirementsArray(ref reader),
JsonTokenType.StartObject => SetCraftingRequirementsObject(ref reader),
_ => craftingRequirements
};
}
catch (Exception)
{
return craftingRequirements;
}
return craftingRequirements;
}
public override void Write(Utf8JsonWriter writer, List<CraftingRequirements> value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
private static List<CraftingRequirements> SetCraftingRequirementsArray(ref Utf8JsonReader reader)
{
var craftingRequirements = new List<CraftingRequirements>();
var craftingRequirement = new CraftingRequirements();
var startDepth = reader.CurrentDepth;
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndArray && reader.CurrentDepth == startDepth)
{
return craftingRequirements;
}
if (reader.TokenType == JsonTokenType.StartObject)
{
craftingRequirement = new CraftingRequirements();
}
if (reader.TokenType == JsonTokenType.EndObject)
{
craftingRequirements.Add(craftingRequirement);
}
if (reader.TokenType == JsonTokenType.PropertyName)
{
var propertyName = reader.GetString();
switch (propertyName)
{
case "@silver":
reader.Read();
craftingRequirement.Silver = reader.GetString();
break;
case "@time":
reader.Read();
craftingRequirement.Time = reader.GetString();
break;
case "@craftingfocus":
reader.Read();
craftingRequirement.CraftingFocus = reader.GetString();
break;
case "craftresource":
reader.Read();
craftingRequirement.CraftResource = reader.TokenType switch
{
JsonTokenType.StartArray => SetCraftResourceArray(ref reader),
JsonTokenType.StartObject => SetCraftResourceObject(ref reader),
_ => craftingRequirement.CraftResource
};
break;
case "@swaptransaction":
reader.Read();
craftingRequirement.SwapTransaction = reader.GetString();
break;
case "playerfactionstanding":
reader.Read();
craftingRequirement.PlayerFactionStanding = SetPlayerFactionStanding(ref reader);
break;
case "currency":
reader.Read();
craftingRequirement.Currency = SetCurrency(ref reader);
break;
case "@amountcrafted":
reader.Read();
craftingRequirement.AmountCrafted = reader.GetString();
break;
case "@forcesinglecraft":
reader.Read();
craftingRequirement.ForceSingleCraft = reader.GetString();
break;
}
}
}
return craftingRequirements;
}
private static List<CraftingRequirements> SetCraftingRequirementsObject(ref Utf8JsonReader reader)
{
var craftingRequirements = new List<CraftingRequirements>();
var craftingRequirement = new CraftingRequirements();
var startDepth = reader.CurrentDepth;
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject && reader.CurrentDepth == startDepth)
{
craftingRequirements.Add(craftingRequirement);
return craftingRequirements;
}
if (reader.TokenType == JsonTokenType.PropertyName)
{
var propertyName = reader.GetString();
switch (propertyName)
{
case "@silver":
reader.Read();
craftingRequirement.Silver = reader.GetString();
break;
case "@time":
reader.Read();
craftingRequirement.Time = reader.GetString();
break;
case "@craftingfocus":
reader.Read();
craftingRequirement.CraftingFocus = reader.GetString();
break;
case "craftresource":
reader.Read();
craftingRequirement.CraftResource = reader.TokenType switch
{
JsonTokenType.StartArray => SetCraftResourceArray(ref reader),
JsonTokenType.StartObject => SetCraftResourceObject(ref reader),
_ => craftingRequirement.CraftResource
};
break;
case "@swaptransaction":
reader.Read();
craftingRequirement.SwapTransaction = reader.GetString();
break;
case "playerfactionstanding":
reader.Read();
craftingRequirement.PlayerFactionStanding = SetPlayerFactionStanding(ref reader);
break;
case "currency":
reader.Read();
craftingRequirement.Currency = SetCurrency(ref reader);
break;
case "@amountcrafted":
reader.Read();
craftingRequirement.AmountCrafted = reader.GetString();
break;
case "@forcesinglecraft":
reader.Read();
craftingRequirement.ForceSingleCraft = reader.GetString();
break;
}
}
}
return craftingRequirements;
}
private static List<CraftResource> SetCraftResourceArray(ref Utf8JsonReader reader)
{
var craftResources = new List<CraftResource>();
var craftResource = new CraftResource();
var startDepth = reader.CurrentDepth;
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndArray && reader.CurrentDepth == startDepth)
{
return craftResources;
}
if (reader.TokenType == JsonTokenType.StartObject)
{
craftResource = new CraftResource();
}
if (reader.TokenType == JsonTokenType.EndObject)
{
craftResources.Add(craftResource);
}
if (reader.TokenType == JsonTokenType.PropertyName)
{
var propertyName = reader.GetString();
switch (propertyName)
{
case "@uniquename":
reader.Read();
craftResource.UniqueName = reader.GetString();
break;
case "@count":
reader.Read();
if (int.TryParse(reader.GetString(), out var count))
{
craftResource.Count = count;
break;
}
craftResource.Count = 0;
break;
case "@maxreturnamount":
reader.Read();
craftResource.MaxReturnAmount = reader.GetString();
break;
case "@enchantmentlevel":
reader.Read();
craftResource.EnchantmentLevel = reader.GetString();
break;
}
}
}
return craftResources;
}
private static List<CraftResource> SetCraftResourceObject(ref Utf8JsonReader reader)
{
var craftResources = new List<CraftResource>();
var newCraftResource = new CraftResource();
var startDepth = reader.CurrentDepth;
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject && reader.CurrentDepth == startDepth)
{
craftResources.Add(newCraftResource);
return craftResources;
}
if (reader.TokenType == JsonTokenType.PropertyName)
{
var propertyName = reader.GetString();
switch (propertyName)
{
case "@uniquename":
reader.Read();
newCraftResource.UniqueName = reader.GetString();
break;
case "@count":
reader.Read();
if (int.TryParse(reader.GetString(), out var count))
{
newCraftResource.Count = count;
break;
}
newCraftResource.Count = 0;
break;
case "@maxreturnamount":
reader.Read();
newCraftResource.MaxReturnAmount = reader.GetString();
break;
case "@enchantmentlevel":
reader.Read();
newCraftResource.EnchantmentLevel = reader.GetString();
break;
}
}
}
return craftResources;
}
private static PlayerFactionStanding SetPlayerFactionStanding(ref Utf8JsonReader reader)
{
var playerFactionStanding = new PlayerFactionStanding();
var startDepth = reader.CurrentDepth;
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject && reader.CurrentDepth == startDepth)
{
return playerFactionStanding;
}
if (reader.TokenType == JsonTokenType.PropertyName)
{
var propertyName = reader.GetString();
switch (propertyName)
{
case "@faction":
reader.Read();
playerFactionStanding.Faction = reader.GetString();
break;
case "@minstanding":
reader.Read();
playerFactionStanding.MinStanding = reader.GetString();
break;
}
}
}
return playerFactionStanding;
}
private static Currency SetCurrency(ref Utf8JsonReader reader)
{
var currency = new Currency();
var startDepth = reader.CurrentDepth;
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject && reader.CurrentDepth == startDepth)
{
return currency;
}
if (reader.TokenType == JsonTokenType.PropertyName)
{
var propertyName = reader.GetString();
switch (propertyName)
{
case "@uniquename":
reader.Read();
currency.UniqueName = reader.GetString();
break;
case "@amount":
reader.Read();
currency.Amount = reader.GetString();
break;
}
}
}
return currency;
}
}
Upvotes: 1
Reputation: 1175
add the Nuget-Package 'Newtonsoft.Json' to your project and try this. You propably need some fine tuning, but you should get the idea.
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string json = @"{
'weapon': [
{
'@uniquename': 'T3_2H_QUARTERSTAFF',
'craftingrequirements': [
{
'@silver': '0',
'@time': '5',
'@craftingfocus': '16085',
},
{
'@silver': '0',
'@time': '5',
'@craftingfocus': '16085'
}
]
},
{
'@uniquename': 'T6_2H_QUARTERSTAFF_AVALON',
'craftingrequirements': {
'@silver': '0',
'@time': '1',
'@craftingfocus': '980'
}
}
]
}";
JObject o = JObject.Parse(json);
foreach (var w in o["weapon"])
{
var r2 = w["craftingrequirements"];
if (r2 is JArray)
{
var res = JsonConvert.DeserializeObject<CraftingRequirements[]>(r2.ToString ().Replace("@", "") );
}
else
{
var res = JsonConvert.DeserializeObject<CraftingRequirements>(r2.ToString().Replace("@", ""));
}
}
}
}
public class CraftingRequirements
{
public string silver { get; set; }
public string time { get; set; }
public string craftingfocus { get; set; }
}
}
Upvotes: 1