5

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.

7
  • 1
    What is the error message you get when it fails? Reason I ask, shouldn't the DeserializeObject be throwing the exception if it's related to the constructor, as this is when it has to construct the object again. Commented Jul 20, 2015 at 8:10
  • Is the MyObject class sealed? Can you inherit it? Commented Jul 20, 2015 at 8:32
  • @MarioStoilov It's not sealed. Commented Jul 21, 2015 at 6:20
  • you could try inheriting the class and defining a parameterless constructor in the new class Commented Jul 21, 2015 at 9:52
  • @MarioStoilov you cannot do that in C#. The constructor is internal. Commented Jul 21, 2015 at 11:20

3 Answers 3

8

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).
Sign up to request clarification or add additional context in comments.

1 Comment

The proposed solution can't be used, because source code cannot be changed (take this as a fact) as was stated in a question.
2

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);
    }
}

Comments

1

You could use a proxy class with similar properties:

public sealed class TargetClass{
    public static readonly TargetClass tc = new TargetClass();
    public int Id;
    public string SomeName;
    private TargetClass(){
        this.Id=50;
        this.SomeName="My, What Bastardry";
    }
}
public class ProxyClass{
    public int Id {get; set;}
    public string SomeName {get; set;}
    public ProxyClass(){
    }
    public ProxyClass(int id, string somename){
        Id = id;
        SomeName = somename;
    }
}
public class Program
{
    public static void Main()
    {
        TargetClass tgt = TargetClass.tc;
        ProxyClass pc = new ProxyClass(tgt.Id,tgt.SomeName);
        string s = JsonConvert.SerializeObject(pc);
        Console.WriteLine(s);
    }
}

1 Comment

Quick and dirty example using Reflection and a proxy object, but you can use it in conjunction with the custom JsonConvertors mentioned by others: dotnetfiddle.net/OtOXSm

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.