I want to use JSON to serialize between JSON files and some nested classes I have. The problem I’m having is it’s difficult to set them up without making the variables public and editable by external sources.
To make a variable/class accessible by the JSON Serializser (either JSONUtility or System.Web.Script.Serialization) the variable must be public. The issue is I don’t want to make these variables changeable at runtime by an external programmer (they are in a managed dll module).
I can’t use public properties or internal variables as the JSON serializer won’t accept them. So I’m unsure how I can avoid making them public and editable . This is what they look like:
#1
May 3rd 2016, 1:44:35 pm
VALID JSON (RFC 4627)
Formatted JSON Data
{
"Contents":[
{
"name":"Chapter 1",
"description":"First Chapter Description",
"isComplete":false,
"percentageComplete":0,
"sections":[
{
"tests":[
{
"id":"TEST_001_001_0001",
"name":"First Test Description",
"description":"Do Test - chapter 1 section 1 test 1",
"isComplete":false
},
using System.Web.Script.Serialization;
namespace Learning
{
/// <summary>
/// These are equal to one single point. The sum of these equal the completion of a section, and subsequent chapter.
/// </summary>
public class Test
{
public Test(){ } // Standard constructor kepy as JSON Serializer cannot handle constructor parameters
public Test(string id, string name, string description)
{
this.name = name;
this.id = id;
this.description = description;
}
public string id;
public string name;
public string description;
public bool isComplete { get; protected set; }
/// <summary>
/// Modify complete property externally
/// </summary>
/// <param name="isComplete"></param>
public void SetComplete(bool isComplete)
{
this.isComplete = isComplete;
}
}
}
Thanks for responding. I’m not meaning visible in the Inspector to designers. I mean visible to anything outside of it’s own dll module. Including any Unity Scripts. So for example the following would be considered immutable to an external program:
public string id { get; private set; }
public const string id = "someID";
public readonly string id;
internal string id;
However I cannot force JSONUtility or .NET’s serializer to find anything other than a bog standard public variable.
My module doesn’t even contain the UnityEngine/UnityEditor dll’s anymore, as I want to have my modules cross engine.
Consider using something like Memento pattern. For your business logic class with properly encapsulated data, create corresponding POCODTO for serialization purposes only. Add methods like GetMemento() and CreateFromMemento(). So MyActualClass is properly encapsulated with no public fields; and MyClassMemento contains no logic, just public simple fields for serialization.
You may notice that the documentation for the JavaScriptSerializer you’re using actually says at the top of its page:
I swear, that doc page is awful! It must be a one-off class that was put in for the web api, and then obsoleted in favor of Json.NET, and only kept in there for backwards compatibility.
It’s better to split logic classes from DTO regardless of actual serialization technology used: MiniJSON, UnityEngine.JsonUtility, Newtonsoft Json.NET, etc.
Just to add to this, my Unity port of JSON .NET is getting ready for an update. I’ve been migrating it to JSON .NET 8.0.4 (the latest and greatest) in which case it will now support CustomCreationConverter in addition to JsonConverter which will allow you to use an alternate constructor.