Want to convert a object to a json string and back.
My object:
[Serializable]
public class Save
{
public Levels PlayerLvl { get; set; }
public int Kills { get; set; }
}
function in code:
testfunction(Save savedata) {
//(int)savedata.PlayerLvl equals 1
//savedata.Kills equals 5
string json = JsonUtility.ToJson(savedata);
debug.log(json) // json equals "{}"
}
The same happens when I get a json string and want to convert it back:
testFunction(string jsonstring) {
//jsonstring is a valid json string that equals Save object
Save savedata = JsonUtility.FromJson<Save>(jsonstring);
// savedate equals a new Save object without content
}
whats wrong here?
Edit:
Json that I get:
{
"Kills": 5,
"PlayerLvl": 1
}
Levels enum:
public enum Levels {
Level1 = 1,
Level2 = 2
}
See from Manual: JSON Serialization
Supported types
The JSON Serializer API supports any MonoBehaviour subclass, ScriptableObject subclass, or plain class or struct with the [Serializable] attribute. When you pass in an object to the standard Unity serializer for processing, the same rules and limitations apply as they do in the Inspector: Unity serializes fields only; and types like Dictionary<> are not supported.
Unity does not support passing other types directly to the API, such as primitive types or arrays. If you need to convert those, wrap them in a class or struct of some sort.
So you want to remove all {get; set;} in order to use fields not properties
[Serializable]
public class Save
{
public Levels PlayerLvl;
public int Kills;
}
Related
I have a source JSON object that I get from a server that looks like this:
{
"Property A": .098
}
I have a C# class that I deserialize the JSON into using the following:
public class foo {
[JsonProperty("Property A")]
public decimal PropertyA{ get; set;}
}
var ret = JsonConvert.DeserializeObject<foo>(File.ReadAllText(someJsonString);
This allows me to read in a JSON file and convert it to a C# object. But now I would like to write this object out to JSON but change the format to be this:
{
"property_a":.098
}
I currently have another class that is identical and the only difference is that I change the JsonProperty field to the new desired name:
public class foo {
[JsonProperty("property_a")]
public decimal PropertyA{ get; set; }
}
Is there a way using Newtonsoft to have a JsonProperty read as a particular value but write as a different?
I need to customize the way Newtonsoft.Json serializes an object, in particular about Enum types.
Given a sample class like this:
public class TestEnumClass
{
public Enum ReferencedEnum { get; set; }
public string OtherProperty { get; set; }
public StringSplitOptions OtherEnum { get; set; }
}
The default serialization will happen this way:
var testEnumClass = new TestEnumClass
{
ReferencedEnum = StringComparison.OrdinalIgnoreCase,
OtherProperty = "Something",
OtherEnum = StringSplitOptions.None
};
var serialized = JsonConvert.SerializeObject(testEnumClass, Formatting.Indented);
And the serialized string will be:
{
"ReferencedEnum": 5,
"OtherProperty": "Something",
"OtherEnum": 0
}
Here I have 2 problems:
I cannot guarantee that the order of the Enums will remain the same (here I am using Enums included in the framework, but my project has other Enums that derive from ": Enum"), so I cannot keep the number as the serialized value of the Enum.
Secondly, and more important, is the fact that the "ReferencedEnum" field is declared as "Enum", and any kind of Enum can be written in that field (ReferencedEnum = AnyEnum.AnyEnumValue).
This leads to the fact that when deserializing the value, I need to know the original Enum type (in the example is StringComparison).
I was thinking of using a Converter (deriving from ": JsonConverter") and manipulating what is written and read. The result I was thinking was something like this:
{
"ReferencedEnum": {
"EnumType": "StringComparison",
"EnumValue": "OrdinalIgnoreCase"
},
"OtherProperty": "Something",
"OtherEnum": "StringSplitOptions.None"
}
I this way the deserializer would know:
for "Enum" properties, the original type and the string value.
for "typed Enum" (specific enum) properties, the full type and value.
What I cannot absolutely add is a reference to the converter in the model class like this:
[JsonConverter(typeof(EnumConverter))]
public Enum ReferencedEnum { get; set; }
And I also would avoid to have the "$type" field in the serialized string (except if this is the only solution).
By the way, I can add a generic attribute like this:
[IsEnum]
public Enum ReferencedEnum { get; set; }
Does somebody have any idea of how can I get the result needed?
Thank you!
I've been in the very same issue and developed a nuget package named StringTypeEnumConverter, that solves it.
You can check the project here.
The usage will be as simple as any other converter.
This converter derives from an already existing "StringEnumConverter", that writes the string value of the enum, instead of its numeric counterpart.
I added the support to writing the type name too.
The result will be like: "StringSplitOptions.None" (this is a string value, not an object).
Note that this converter should be applied for both writing and reading, as the resulting json would not be compatible with other readers not including this converter.
You should consider using this package only if you cannot avoid using enums in your model.
I would also suggest you to spend time to check if (custom) enums could be transformed to classes.
J.
I'm working on a Unity (C#) project and trying to convert JSON data from an API to a list of dictionaries. I'm trying to use Unity's JSONSerialization, but I'm not sure what to do.
In the documentation, it says the following, and I was wondering if anyone could guide me to how I can convert the JSON? Sorry for the easy question as I'm new to C# and in the other languages I use like Javascript/Python, this is quite easily done.
Passing other types directly to the API, for example primitive types
or arrays, is not currently supported. For now you will need to wrap
such types in a class or struct of some sort.
https://docs.unity3d.com/Manual/JSONSerialization.html
The JSON returned is as follows and is a list of dictionaries, and each dictionary has two keys (_id and firstName).
[{"_id":"xxx", "firstName":"Brayann"}, {"_id":"yyy", "firstName":"Peter"}]
Create object in which you will Deserialize the json. Call ToDictionary after that.
Full example: dotNetFiddle
public static void Main(string[] args)
{
string json = #"[{ ""_id"":""xxx"", ""firstName"":""Brayann""}, { ""_id"":""yyy"", ""firstName"":""Peter""}]";
var result = JsonConvert.DeserializeObject<List<RootListObject>>(json)
.ToDictionary(x=> x.id, y=> y.firstName);
}
public class RootListObject
{
[JsonProperty(PropertyName ="_id")]
public string id { get; set; }
public string firstName { get; set; }
}
As far as I know you can't deserialize as enumarable of dictionary but you can create a class for this purpose which is more reasonable:
public class SomeDataType
{
public string _id { get; set; }
public string firstName { get; set; }
}
Then you can deserialize as List<SomeDataType>.
Even if you really require the dictionary you can add a ToDictionary method to your class.
I have an object structure like this:
public class Proposal {
public List<ProposalLine> Lines { get; set; }
public string Title { get; set; }
}
public class ProposalLine {
public Proposal Proposal { get; set; } // <- Reference to parent object
}
I try to serialize Proposal as Json, it tells me that there is a circular reference, which is correct.
Unfortunately, I can't touch the objects, since they are in a referenced DLL from another project - otherwise I'd change them.
Is there a way to serialize as Json and ignore the circular properties?
Use the Newtonsoft.Json (which is the default .net json serializer) and set
JsonSerializerSettings settings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects
};
var serializer = JsonSerializer.Create(settings);
You can also globally define this variable if you are developing MVC applications...
I have the following code and json:
public class Labels
{
public Labels()
{}
public Label[] Label {get;set;}
}
public class Label
{
public Label()
{ }
public string Name { get; set; }
public int TorrentsInLabel { get; set; }
}
//...
Labels o = JsonConvert.DeserializeObject<Labels>(json);
//...
{"label":
[
["seq1",1]
,["seq2",2]
]}
I would like this array ["seq1","1"] to deserialize into Label object. What am I missing? Some attributes?
When I run I get exception: Expected a JsonArrayContract for type 'test_JSONNET.Label', got 'Newtonsoft.Json.Serialization.JsonObjectContract'.
tnx
gg
How can JsonConvert know that "seq1" corresponds to name and "1" corresponds to the TorrentsInLabel? Please have a look at JsonObjectAttribute, JsonPropertyAttribute, JsonArrayAttribute
By default a class serializes to a JSON object where the properties on the class become properties on the JSON object.
{
Name: "seq",
TorrentsInLabel: 1
}
You are trying to serialize it to an array which isn't how the Json.NET serializer works by default.
To get what you want you should create a JsonConverter and read and write the JSON for Label manually to be what you want it to be (an array).