32

I have class with some internal properties and I would like to serialize them into json as well. How can I accomplish this? For example

public class Foo
{
    internal int num1 { get; set; }
    internal double num2 { get; set; }
    public string Description { get; set; }

    public override string ToString()
    {
        if (!string.IsNullOrEmpty(Description))
            return Description;

        return base.ToString();
    }
}

Saving it using

Foo f = new Foo();
f.Description = "Foo Example";
JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All };

 string jsonOutput = JsonConvert.SerializeObject(f, Formatting.Indented, settings);

 using (StreamWriter sw = new StreamWriter("json_file.json"))
 {
     sw.WriteLine(jsonOutput);
 }

I get

{  
"$type": "SideSlopeTest.Foo, SideSlopeTest",
"Description": "Foo Example"
}
Farukh
  • 2,173
  • 2
  • 23
  • 38
  • 4
    Usually internal properties are not intended to be leaving the boundaries of the current assembly and thus being serialized. Why would you need to do that? If you want a proper JSON representation you might need a DTO to map your internal/private stuff to and then serialize. – Darin Dimitrov Nov 11 '14 at 20:21
  • +1 what @DarinDimitrov said. But if you really want to do it, I believe you need to subclass `DefaultContractResolver` to make it look at non-public properties as well. – s.m. Nov 11 '14 at 20:24
  • 1
    possible duplicate of [JSON.Net: Force serialization of all private fields and all fields in sub-classes](http://stackoverflow.com/questions/24106986/json-net-force-serialization-of-all-private-fields-and-all-fields-in-sub-classe) – David L Nov 11 '14 at 20:25
  • 3
    Just mark them with the [`[JsonProperty()]`](http://james.newtonking.com/json/help/index.html?topic=html/T_Newtonsoft_Json_JsonPropertyAttribute.htm) attribute. – dbc Nov 11 '14 at 20:27
  • if the class is also internal mark it with `[JsonObject()]` – CAD bloke Feb 19 '18 at 13:23

1 Answers1

50

Mark the internal properties to be serialized with the [JsonProperty] attribute:

public class Foo
{
    [JsonProperty]
    internal int num1 { get; set; }
    [JsonProperty]
    internal double num2 { get; set; }

    public string Description { get; set; }

    public override string ToString()
    {
        if (!string.IsNullOrEmpty(Description))
            return Description;

        return base.ToString();
    }
}

And then later, to test:

Foo f = new Foo();
f.Description = "Foo Example";
f.num1 = 101;
f.num2 = 202;
JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All };

var jsonOutput = JsonConvert.SerializeObject(f, Formatting.Indented, settings);

Console.WriteLine(jsonOutput);

I get the following output:

{
  "$type": "Tile.JsonInternalPropertySerialization.Foo, Tile",
  "num1": 101,
  "num2": 202.0,
  "Description": "Foo Example"
}

(Where "Tile.JsonInternalPropertySerialization" and "Tile" are namespace and assembly names I am using).

As an aside, when using TypeNameHandling, do take note of this caution from the Newtonsoft docs:

TypeNameHandling should be used with caution when your application deserializes JSON from an external source. Incoming types should be validated with a custom SerializationBinder when deserializing with a value other than None.

For a discussion of why this may be necessary, see TypeNameHandling caution in Newtonsoft Json and and External json vulnerable because of Json.Net TypeNameHandling auto?.

Community
  • 1
  • 1
dbc
  • 104,963
  • 20
  • 228
  • 340
  • I just deleted my answer saying that internal properties are not accessible outside the assembly because this is news to me. How is a serializer able to access these across assemblies? Is this not somewhat of a security problem? – esmoore68 Apr 14 '16 at 16:28
  • 4
    @esmoore68 - The serializer uses reflection. See e.g. https://stackoverflow.com/questions/1565734/is-it-possible-to-set-private-property-via-reflection and https://stackoverflow.com/questions/30191282/isnt-accessing-private-fields-and-properties-due-to-reflection-a-security-issue. – dbc Apr 14 '16 at 16:34
  • in addition to @dbc answer, what is reported is still valid also for internal-visibility classes and private-visibility (nested) classes – Giacomo Pirinoli Dec 22 '21 at 11:17