Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json.NET - how to serialize an external class with internal constructor?

I need to serialize a class which it's source code cannot be changed (take this as a fact), and it's from a different assembly. It has only one constructor

public class MyObject
{
    string _s;
    int _i;
    internal MyObject(string s, int i)
    {
        // ...
    }
}

JsonConvert.SerializeObject(object) fails of course because of this. I wonder if there is a way to use Json.NET to serialize this class without having to adding code or even tags to it.

like image 322
shay__ Avatar asked Dec 19 '22 02:12

shay__


2 Answers

If you have a parameterless constructor, you should be able to do this by adding the following setting:

JsonSerializerSettings settings = new JsonSerializerSettings()
{
    ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
};

var serializedJson = JsonConvert.DeserializeObject<MyObject>(jsonString, settings);

Update after question edit:

If you don't have any public constructors and you don't have a parameterless constructor, then I only know of 2 options:

  1. Add the [JsonConstructor] attribute to your internal constructor (which doesn't seem an option in your case as you cannot edit the class).
  2. Create a proxy class with similar properties (not as elegant but no change to the class needed).
like image 82
Niels Filter Avatar answered Jan 18 '23 23:01

Niels Filter


You should use a custom JsonConverter.

The solution would be something like

public class MyObjectProxy
{
    public string s { get; set; }
    public int i { get; set; }
}

public class MyObjectJsonConverter : JsonConverter
{
    public override void WriteJson(
        JsonWriter writer, object value, JsonSerializer serializer)
    {
        // Create an instance of MyObjectProxy, copy values from the
        // instance of MyObject, write JSON from the MyObjectProxy.
    }

    public override object ReadJson(
        JsonReader reader, Type type, object value, JsonSerializer serializer)
    {
        // Deserialize MyObjectProxy, create an instance of MyObject,
        // copy properties from the deserialized MyObjectProxy.
    }

    public override bool CanConvert(Type type)
    {
        return typeof(MyObject).IsAssignableFrom(type);
    }
}
like image 45
kyrylomyr Avatar answered Jan 18 '23 22:01

kyrylomyr