'Shorten JSON reading class
I have a simple JSON reading class that should grab values from a JSON object and put it in c# variables. Right now it uses 8 if statements, but I was wondering if this can be done in a smoother way.
current code:
public Game Read(string filePath)
{
string fileName = "./Levels/TempleOfDoom.json";
JObject json = JObject.Parse(File.ReadAllText(fileName));
Game game = new Game();
foreach (JObject jconnection in json["rooms"])
{
Room room = new Room();
foreach (JProperty jProperty in jconnection.Children().OfType<JProperty>())
{
if (jProperty.Name == "id")
room.id = jProperty.Value.ToObject<int>();
if (jProperty.Name == "width")
room.width = jProperty.Value.ToObject<int>();
if (jProperty.Name == "height")
room.height = jProperty.Value.ToObject<int>();
foreach (JObject jconnection2 in jconnection["items"])
{
Item item = new Item();
foreach (JProperty jProperty2 in jconnection.Children().OfType<JProperty>())
{
if (jProperty.Name == "type")
item.type = jProperty2.Value.ToObject<string>();
if (jProperty.Name == "x")
item.x = jProperty2.Value.ToObject<int>();
if (jProperty.Name == "y")
item.y = jProperty2.Value.ToObject<int>();
if (jProperty.Name == "damage")
item.damage = jProperty2.Value.ToObject<int>();
if (jProperty.Name == "color")
item.color = jProperty2.Value.ToObject<string>();
}
}
}
game.Rooms.Add(room);
}
return game;
}
relevant part of JSON object:
{
"rooms": [
{
"id": 1,
"type": "room",
"width": 5,
"height": 5
},
{
"id": 2,
"type": "room",
"width": 3,
"height": 3
},
{
"id": 3,
"type": "room",
"width": 5,
"height": 5,
"items": [
{
"type": "disappearing boobietrap",
"damage": 1,
"x": 2,
"y": 1
},
{
"type": "sankara stone",
"x": 2,
"y": 2
}
]
},
{
"id": 4,
"type": "room",
"width": 11,
"height": 7,
"items": [
{
"type": "key",
"color": "green",
"x": 1,
"y": 1
},
{
"type": "sankara stone",
"x": 5,
"y": 3
},
{
"type": "boobietrap",
"damage": 1,
"x": 4,
"y": 2
},
{
"type": "boobietrap",
"damage": 1,
"x": 5,
"y": 2
},
{
"type": "boobietrap",
"damage": 1,
"x": 6,
"y": 2
},
{
"type": "boobietrap",
"damage": 1,
"x": 4,
"y": 4
},
{
"type": "boobietrap",
"damage": 1,
"x": 5,
"y": 4
},
{
"type": "boobietrap",
"damage": 1,
"x": 6,
"y": 4
}
]
},
{
"id": 5,
"type": "room",
"width": 5,
"height": 5,
"items": [
{
"type": "key",
"color": "red",
"x": 2,
"y": 3
},
{
"type": "sankara stone",
"x": 2,
"y": 2
}
]
},
{
"id": 6,
"type": "room",
"width": 3,
"height": 3,
"items": [
{
"type": "sankara stone",
"x": 1,
"y": 1
}
]
},
{
"id": 7,
"type": "room",
"width": 5,
"height": 3,
"items": [
{
"type": "pressure plate",
"x": 2,
"y": 1
}
]
},
{
"id": 8,
"type": "room",
"width": 3,
"height": 3
},
{
"id": 9,
"type": "room",
"width": 5,
"height": 5,
"items": [
{
"type": "sankara stone",
"x": 2,
"y": 2
},
{
"type": "boobietrap",
"damage": 1,
"x": 1,
"y": 3
},
{
"type": "boobietrap",
"damage": 1,
"x": 2,
"y": 3
},
{
"type": "boobietrap",
"damage": 1,
"x": 3,
"y": 3
}
]
}
],
}
As you can see, each room has an ID, width and height (type can be ignored) and some rooms have items, which all have a type, x and y coordinate, and some have colors or damage numbers. Is there a better way to get all of these values into a C# class? A game has a List of rooms, and each room can possibly have a list of items.
EDIT: Thanks guys! These lines of code did exactly what I wanted (together with some extra classes for each object game/player/item etc.
public Game Read(string fileName)
{
JObject json = JObject.Parse(File.ReadAllText(fileName));
return JsonConvert.DeserializeObject<Game>(json.ToString());
}
Solution 1:[1]
My advice would be to use a webpage called https://json2csharp.com/ that it will create the model class for your json. Sometimes it needs a little tweaking, then is as easy as calling
var json = JsonConverter.DeserializeObject<YourJsonClass>(File.ReadAllText(fileName))
And you would have a class representing your json file, and if you still need to move this information to your custom classes you wouldnt need the if at all just do something like
foreach (var jsonRoom in json.Rooms)
{
room.id = jsonRoom.id;
//and so on
}
Solution 2:[2]
You can create a class, for example:
public class Item
{
public string type { get; set; }
public int damage { get; set; }
public int x { get; set; }
public int y { get; set; }
public string color { get; set; }
}
public class Room
{
public int id { get; set; }
public string type { get; set; }
public int width { get; set; }
public int height { get; set; }
public List<Item> items { get; set; }
}
public class MyClass
{
public List<Room> rooms { get; set; }
}
And then deserialize the object as:
MyClass myDeserializedClass = JsonConvert.DeserializeObject<MyClass>(json.ToString());
And then you can access all inside of MyClass
and iterate over List<Room>
using foreach
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Brian Rogers |