I'm working on a game that uses a grid of hex-shaped tiles. The tiles are saved as this class:
[System.Serializable]
public class Tile
{
public Hex location;
public TerrainType terrainType;
public Color color { get { return terrainType.color; } }
public int distance;
public string label;
public int cost { get { return terrainType.baseMPCost; } }
public int new_cost;
}
Hex is this struct, used to mark the coordinates of the tile in the hex grid:
public struct Hex
{
//private int _q, _r; originally this used a getter/setter for some reason
public int q;
public int r;
public Hex (int Q, int R)
{
q = Q;
r = R;
}
public int s
{
get { return -q - r; }
}
public float x
{
get { return (3f / 2f) * HexMetrics.outerRadius * q; }
}
public float y
{
get { return (Mathf.Sqrt(3f) / 2f * HexMetrics.outerRadius * q + Mathf.Sqrt(3f) * HexMetrics.outerRadius * r); }
}
}
Finally, TerrainType is this struct:
[System.Serializable]
public struct TerrainType
{
public TerrainType(string Name, int BaseMPCost, Color Color)
{
name = Name;
baseMPCost = BaseMPCost;
color = Color;
}
public string name;
public int baseMPCost;
public Color color;
}
All of the tiles are saved as a list in my map script. I'm using the JsonHelper Script from the top comment on this thread, which writes the list to an array, producing this file.
However, loading the file with the same script gives this error:
ArgumentException: JSON parse error: Invalid value.
UnityEngine.JsonUtility.FromJson (System.String json, System.Type type) (at <1a491ffb1c7c42349a050cc1542277fb>:0)
UnityEngine.JsonUtility.FromJson[T] (System.String json) (at <1a491ffb1c7c42349a050cc1542277fb>:0)
JsonHelper.FromJson[T] (System.String json) (at Assets/Scripts/JsonHelper.cs:9)
InputStateMapEdit.HandleInput () (at Assets/Scripts/StateMachine/InputStates/InputStateMapEdit.cs:57)
InputManager.Update () (at Assets/Scripts/InputManager.cs:40)
When I paste the file into json2csharp.com, it interprets it like this:
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class Color
{
public double r { get; set; }
public double g { get; set; }
public double b { get; set; }
public double a { get; set; }
}
public class Grid
{
public Location location { get; set; }
public TerrainType terrainType { get; set; }
public int distance { get; set; }
public string label { get; set; }
public int new_cost { get; set; }
}
public class Location
{
public int q { get; set; }
public int r { get; set; }
}
public class Root
{
public int Width { get; set; }
public int Height { get; set; }
public List<Grid> Grid { get; set; }
}
public class TerrainType
{
public string name { get; set; }
public int baseMPCost { get; set; }
public Color color { get; set; }
}
I'm not exactly sure why it can't convert this back into the structs and classes I wrote originally, but a lot of them seem to be renamed, are missing some data, etc. Also, the entire list of tiles doesn't appear at all, just their basic components. Is there something preventing them from being properly serialized and written to the JSON file? I think I could probably create another class that stores all the relevant data points as normal floats and integers, then create all new tiles based on them, but I don't want to do that for everything I try to save (especially scenarios, which will include units and such with lots of data) in the future.
Edit - Here is the actual code that writes the Json file:
var m = map.grid.ToArray();
string grid = JsonHelper.ToJson<Tile>(m);
File.WriteAllText("C:/SG/Strategy Game/Assets/test.json", grid);
And the code that reads it:
var m = JsonHelper.FromJson<Tile>("C:/SG/Strategy Game/Assets/test.json");
map.grid = m.ToList();
The problem is that the JsonUtility doesn't support serializing just an array..
... Similarly, passing an array to this method will not produce a JSON array containing each element, but an object containing the public fields of the array object itself (of which there are none). To serialize the actual content of an array or primitive type, it is necessary to wrap it in a class or struct.
To serialize the array properly, we just need a small wrapper class:
[System.Serializable]
public class TileListWrapper {
public Tile[] tiles;
}
and then we create a new TileListWrapper and serialize that instead:
var m = map.grid.ToArray();
var wrapper = new TileListWrapper() {
tiles = m,
};
string grid = JsonUtility.ToJson<TileListWrapper>(wrapper);
File.WriteAllText("C:/SG/Strategy Game/Assets/test.json", grid);
and also deserialize into TileListWrapper:
var wrapper = JsonUtility.FromJson<TileListWrapper>("C:/SG/Strategy Game/Assets/test.json");
map.grid = wrapper.tiles.ToList();
Im having trouble in parsin JSON in C#. I want to parse this Json Format.
{
"data":
[
{
"id": 3,
"code": "0000004",
}
]
}
Here is my code in C#.
public Data data { get; set; }
public class Data
{
public string id { get; set; }
public string code { get; set; }
}
The JSON shown is an object that has (as data) an array of elements that have an id and code, so:
public class SomeRoot {
public List<Data> data {get;} = new List<Data>();
}
and deserialize a SomeRoot and you should be fine:
var root = JsonConvert.DeserializeObject<SomeRoot>(json);
var obj = root.data[0];
Console.WriteLine(obj.id);
Console.WriteLine(obj.code);
You are missing an essential part, the outer object. Also, the data is an array:
public class RootObject
{
public Data[] data { get; set; }
}
RootObject r = JsonConvert.DeserializeObject<RootObject>(json);
Next time, follow the steps as outlined in Easiest way to parse JSON response. It will help you generate the correct class.
It should be :
public class Data
{
public int id { get; set; }
public string code { get; set; }
}
public class RootObject
{
public List<Data> data { get; set; }
}
I am new with C#, and so I don't know too much about it. I want to deserialize json object, but I am having some issues.
Thi is json object:
var json = "[{
"idSite":"1",
"visitorId":"a393fed00271f588",
"actionDetails":[{
"type":"action",
"url":"http:\/\/mysite.info\/test-24\/",
"customVariables":{
"1":{
"customVariablePageName1":"URL",
"customVariablePageValue1":"http:\/\/mysite.info\/p"
}
},
"timeSpent":"78",
}]
}]";
And I am trying to deserialize it on this way:
var visits = JsonConvert.DeserializeObject<VisitorDetails[]>(json);
public class VisitorDetails
{
public string idSite { get; set; }
public string visitorId { get; set; }
public List<ActionDetail> actionDetails { get; set; }
}
public class ActionDetail
{
public string type { get; set; }
public string url { get; set; }
public string timeSpent { get; set; }
public object customVariables { get; set; }
}
Everything is fine, except "customVariables" in "ActionDetails" it just set it to object with one value as string:
{
"1":{
"customVariablePageName1":"URL",
"customVariablePageValue1":"http:\/\/mysite.info\/p"
}
}
It doesn't deserialize it at all.
I need this deserialize so I can say:
foreach (var visit in Model.PiwikInfo)
{
#foreach (var action in visit.actionDetails)
{
#if (action.customVariables != null && action.customVariables.Any())
{
foreach (var cv in visit.customVariables.Where(cv => cv.HasProperty("customVariablePageName1")))
{
<span>URL: #cv.GetProperty("customVariablePageValue1")</span>
}
}
}
}
Well, this happens, because you have specified that the customVariables member is of type System.Object. So deserialization will result in assigning it the string value.
So lets try to mold it into a shape that better resembles the input JSON structure and your specific use of the deserialization result, in two steps, by changing the type declaration of the customVariables member variable, and inspecting its deserialized content after each change.
Make it a dictionary:
public Dictionary<string, object> customVariables { get; set; }
This will result in a dictionary that contains a single element with the key "1" and a single string value:
{
"customVariablePageName1": "URL",
"customVariablePageValue1": "http://mysite.info/p"
}
Make it a dictionary of dictionaries:
public Dictionary<string, Dictionary<string, string>> customVariables { get; set; }
And print its deserialized ouput like this:
var visits = JsonConvert.DeserializeObject<VisitorDetails[]>(json_string);
foreach (var visit in visits)
{
Console.WriteLine("Visitor: {0}", visit.visitorId);
foreach (var detail in visit.actionDetails)
{
Console.WriteLine(" Action: {0}", detail.type);
foreach (var cv in detail.customVariables.Where(x => x.Value.ContainsKey("customVariablePageName1")))
{
Console.WriteLine(" Custom variable #{0}", cv.Key);
Console.WriteLine(" Value: {0}", cv.Value["customVariablePageValue1"]);
}
}
}
Which resembles your view's foreach, and will produce the following output:
Visitor: a393fed00271f588
Action: action
Custom variable #1
Value: http://mysite.info/p
Since I can't still comment I will have to post this as an answer. have you tried using the built in function of C#?
See Here
Also, from what I gather, on the Documentation of that method it converts it converts the json into a system object.
Also, from the looks of it it seems like the customVariables segment is either an array or a broken object. I say that because it is missing the square brackets like in the previous declarations, making it look like:
...
"customVariables":[{
"1":[{
"customVariablePageName1":"URL",
"customVariablePageValue1":"http:\/\/mysite.info\/p"
}]
}],
...
Hope it helps.
try this structure
public class T1
{
public string customVariablePageName1 { get; set; }
public string customVariablePageValue1 { get; set; }
}
public class CustomVariables
{
public T1 t1 { get; set; }
}
public class ActionDetail
{
public string type { get; set; }
public string url { get; set; }
public CustomVariables customVariables { get; set; }
public string timeSpent { get; set; }
}
public class RootObject
{
public string idSite { get; set; }
public string visitorId { get; set; }
public List<ActionDetail> actionDetails { get; set; }
}
I'm trying to retrieve values that are stored in a JSON string that I obtain from a website using Newtonsoft.Json.
I have the code below, but I cant work out how to loop through the data to retrieve the Name tag within the Palette->Threads->Name section. The number of thread names may vary from 1 to 15.
The desired outcome of the code below would be to output something like
Colours Used: Black, Light Blue, White etc
Any help would be much appreciated, I've racked my brains looking at other peoples examples, but I've had no luck in applying Dictionary or Lists (I'm still learning .net)
protected void Page_Load(object sender, EventArgs e)
{
string jsondata = "{\"Width\":295,\"Height\":329,\"NumStitches\":1596,\"NumTrims\":1,\"Left\":479,\"Top\":-868,\"Right\":775,\"Bottom\":-539,\"Recipe\":\"Normal\",\"MachineFormat\":\"Tajima\",\"MasterDensity\":40,\"Palette\":{\"Threads\":[{\"Name\":\"Black\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1000\",\"Red\":0,\"Green\":0,\"Blue\":0,\"Type\":\"ttRayon\",\"Thickness\":3},{\"Name\":\"Light Blue\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1029\",\"Red\":0,\"Green\":114,\"Blue\":207,\"Type\":\"ttRayon\",\"Thickness\":3},{\"Name\":\"White\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1001\",\"Red\":255,\"Green\":255,\"Blue\":255,\"Type\":\"ttRayon\",\"Thickness\":3},{\"Name\":\"Mustard Brown\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1165\",\"Red\":255,\"Green\":153,\"Blue\":51,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Midnight Blue\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1242\",\"Red\":0,\"Green\":40,\"Blue\":120,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Jungle Green\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1249\",\"Red\":0,\"Green\":204,\"Blue\":0,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Robin Egg Blue\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1093\",\"Red\":0,\"Green\":255,\"Blue\":255,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Hyacinth\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1112\",\"Red\":125,\"Green\":0,\"Blue\":153,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Aztec Gold\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1125\",\"Red\":255,\"Green\":240,\"Blue\":51,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Evergreen\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1303\",\"Red\":0,\"Green\":73,\"Blue\":51,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Lilac\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1033\",\"Red\":153,\"Green\":0,\"Blue\":153,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Jet Black\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1000\",\"Red\":0,\"Green\":0,\"Blue\":0,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Sapphire\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1076\",\"Red\":0,\"Green\":87,\"Blue\":150,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Bordeaux\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1035\",\"Red\":99,\"Green\":47,\"Blue\":61,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Flesh\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1017\",\"Red\":244,\"Green\":188,\"Blue\":172,\"Type\":\"ttCotton\",\"Thickness\":3}]},\"Needles\":[1,2,3]}";
var output = JsonConvert.DeserializeObject<jsonclass>(jsondata);
int StitchCount = output.NumStitches;
int StitchHeight = output.Height;
int StitchWidth = output.Width;
var pal = output.Palette;
// The following code is wrong, but illustrates what I'm trying to do
Response.Write("Colours used: ");
foreach (thread in pal["Threads"])
{
Response.Write(thread["Name"] & ",");
}
}
public class jsonclass
{
public int Width { get; set; }
public int Height { get; set; }
public int NumStitches { get; set; }
public Object Palette { get; set; }
}
I've stripped it down a bit, but this is a visual representation of the JSON data to help understand it
{
"Width":295,
"Height":329,
"NumStitches":1596,
"Palette":
{
"Threads":
[
{
"Name":"Black",
"Manufacturer":"Madeira 40",
"Code":"1000",
"Red":0,
"Green":0,
"Blue":0,
"Type":"ttRayon",
"Thickness":3
},
{
"Name":"Light Blue",
"Manufacturer":"Madeira 40",
"Code":"1029",
"Red":0,
"Green":114,
"Blue":207,
"Type":"ttRayon",
"Thickness":3
},
{
"Name":"White",
"Manufacturer":"Madeira 40",
"Code":"1001",
"Red":255,
"Green":255,
"Blue":255,
"Type":"ttRayon",
"Thickness":3
}
]},
"Needles":[1,2,3]
}
You should model your JsonClass as follow and add threads etc. as well:
public class JsonClass
{
public int Width { get; set; }
public int Height { get; set; }
public int NumStitches { get; set; }
public Palette Palette { get; set; }
}
public class Palette
{
public IEnumerable<Thread> Threads { get; set; }
}
public class Thread
{
public string Name { get; set;}
...
}
Then you can iterate over the threads with the following code:
foreach (var thread in pal.Threads)
{
Response.Write(thread.Name + ", ");
}
use the following model to Deserialise your json.
public class Palette
{
public List<Thread> Threads { get; set; }
}
public class Thread
{
public string Name { get; set; }
public string Manufacturer { get; set; }
public string Code { get; set; }
public int Red { get; set; }
public int Green { get; set; }
public int Blue { get; set; }
public string Type { get; set; }
public int Thickness { get; set; }
}
public class Colors
{
public int Width { get; set; }
public int Height { get; set; }
public int NumStitches { get; set; }
public Palette Palette { get; set; }
public List<int> Needles { get; set; }
}
On page load
var output = JsonConvert.DeserializeObject<Colors>(jsondata);
then iterate the thread
foreach(var thread in output.Palette.Threads){
//something like you wanted
Response.Write(thread.Name + ",");
}
Solution using JSON.NET built-in LINQ to JSON provider:
JObject jObject = JObject.Parse(jsondata);
JArray threads = (JArray)jObject["Palette"]["Threads"];
var colorsUsed = new StringBuilder();
colorsUsed.Append("Colours used: ");
foreach (var thread in threads)
{
colorsUsed.AppendFormat("{0}, ", thread["Name"]);
}
Response.Write(colorsUsed);
Can't seem to get this working. I have this json string and I want to convert it to a C# object:
{"name":"mousePos","args":[{"mouseDet":{"rid":"1","posx":1277,"posy":275}}]}
I've been trying JavaScriptSerializer but I'm having no luck. I'm unsure how to get the values of posx and posy. Can anyone suggest how I would do this? Thanks for the help.
EDIT:
public class JsonData
{
public string name { get; set; }
}
public Form1()
{
// ---- Other stuff here ----
string json = data.MessageText; // The json string.
JavaScriptSerializer ser = new JavaScriptSerializer();
JsonData foo = ser.Deserialize<JsonData>(json);
MessageBox.Show(foo.name); // Shows 'mousePos'
}
I dropped that into JsonLint and got an error. Its invalid JSON
{
"name": "mousePos",
"args": [
"mouseDet": {
"rid": "1",
"posx": 1277,
"posy": 275
}
} //-- THIS should not be here.
]
}
You just need to extend out your object model a little bit to cover it. Based on what you've got in your example, it would be something like:
public class JsonData
{
public string name { get; set; }
public Arguments[] args { get; set; }
}
public class Arguments
{
public MouseDet mouseDet { get; set; }
}
public class MouseDet
{
public int rid { get; set; }
public int posx { get; set; }
public int posy { get; set; }
}
...
var posx = foo.args[0].mouseDet.posx;
The reason the JSON is not valid is because your "args" property contains a key/value pair inside of square brackets, which is not a valid array. I'm guessing it should be something like:
{
"name":"mousePos",
"args":[{"mouseDet":{"rid":"1","posx":1277,"posy":275}}]
}