Reputation: 2052
I am having trouble understanding the issue I am getting with Json.Net on Mac. I am trying to serialize/deserialize objects like the one below.
The code runs without issues on Windows but generates a Newtonsoft.Json.JsonException "Error creating StringEnumConverter" on Mac (also shown in the image). I am hoping someone does see something in the code or error message that could point me in the right direction. The object contains many more fields but the error sounds like it has something to do with the enums. I am building in Xamarin 6 / Mono .Net 4.5 and I am using Json.Net 8.0.3 for .Net 4.5. Any help greatly appreciated.
Edit 1: Removing the JsonConverter(typeof(StringEnumConverter)) decoration avoids the exception - however, enums are serialized as integers again.
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Lib
{
[DataContract(IsReference = true)]
public class Construction : LibraryComponent
{
public Construction() { }
public override string ToString() { return Serialization.Serialize(this); }
[DataMember]
public string Construction { get; set; } = "defaultConstruction";
...
[DataMember, JsonConverter(typeof(StringEnumConverter)), DefaultValue(InConvAlgo.TARP)]
public InConvAlgo SurfaceConvectionModelInside { get; set; } = InConvAlgo.TARP;
[DataMember, JsonConverter(typeof(StringEnumConverter)), DefaultValue(OutConvAlgo.DOE2)]
public OutConvAlgo SurfaceConvectionModelOutside { get; set; } = OutConvAlgo.DOE2;
...
[DataMember, DefaultValue(1)]
public int Priority { get; set; } = 1;
}
public enum InConvAlgo { Simple, TARP, TrombeWall, AdaptiveConvectionAlgorithm };
public enum OutConvAlgo { DOE2, TARP, MoWiTT, SimpleCombined, AdaptiveConvectionAlgorithm }; // DOE-2,
}
Upvotes: 4
Views: 4901
Reputation: 751
This is a stripping issue. Because the parameter-less constructor is never used explicitly in your code, it gets stripped from your build.
To avoid it, you need to force inclusion of that constructor in your build. There is a range of ways to do that, several of which are described in other answers. I'll add another one specific to Unity3D, which I think is cleaner.
There is a project that is a fork of Json.NET dedicated to tweaking it for Unity3D, which contains a helper class that fixes exactly that: https://github.com/jilleJr/Newtonsoft.Json-for-Unity/wiki/Fix-AOT-using-AotHelper
In the case of StringEnumConverter, you can add this line anywhere in your code and it will solve the issue:
AotHelper.EnsureType<StringEnumConverter>();
Upvotes: 3
Reputation: 466
StringEnumConverter doesn't have its own public constructor which is needed by code. You can use JsonStringEnumConverter which provides public constructor.
replace: [JsonConverter(typeof(StringEnumConverter))] ====> [JsonConverter(typeof(JsonStringEnumConverter))]
And it will work.
Upvotes: 6
Reputation: 31
I had the same issue with mono.
A simple workaround which works for me was to create a class that inherit from StringEnumConverter and use it.
That avoid you from copying the source code of this converter (Json.net has a lot of "utils" class).
No more issue after that.
Upvotes: 3
Reputation: 21
I recently ran into this same problem. Including StringEnumConverter
in my source, as suggested by Adi Unnithan, requires that you additionally copy some Util
classes. Not to mention that changing the namespace of that class in the copied code, probably doesn't jibe with the license. Not changing it puts it in contention with any other referenced version of json.net.
The only solution that I could find was to fork Json.net and build on Mono, then reference the resulting dll in the main project.
Upvotes: 0
Reputation: 303
I hit this in Json.Net 9.01 with Unity3D (runs Mono). The inner exception was something like 'No parameterless constructor for StringEnumConverter'.
I wasn't entirely sure what was going on but I worked around this by duplicating StringEnumConverter into my project under my own namespace/assembly.
Upvotes: 0