3

I've been serializing custom type which has some internal properties but when serializing, it seems that using System.Web.Script.Serialization.JavaScriptSerializer serialize method do not serialize internal properties (as it skips the internal property in serialized string). It can easily be understandable from the following code and output :

public class MyClass
{
    public string Property1 { get; set; }

    internal string Property2 { get; set; }

    public string Property3 { get; set; }
}

JavaScriptSerializer mySerializer = new JavaScriptSerializer();
string jsonString = mySerializer.Serialize(new MyClass()
{
            Property1 = "One",
            Property2 = "Twp",
            Property3 = "Three"
});

The jsonString has following value :

{"Property1":"One","Property3":"Three"}

In output, you can see that serialized string do not have Property2 which is internal property. Is there something logic behind it for not supporting internal property in serialization?

What would be the workaround to serialize internal property(except changing internal to public modifier)?

2
  • It seems counter-intuitive to have a piece of data marked as inaccessible outside of the assembly (internal) also be included by default in a process of sending data to another location entirely (serialization). Commented Apr 14, 2016 at 16:33
  • @Will: It is quite confusing to understand, why did MS had taken consideration of cross assembly issue in serialization as it can easily seen that serialization performed in same assembly quite often Commented Apr 14, 2016 at 17:02

2 Answers 2

4

It's simply not supported in System.Web.Script.Serialization.JavaScriptSerializer.

I'd recommend you switch to Json.NET. All you need to do in that case is mark the internal property with the json property attribute and it'll get picked up by the Json.NET serializer.

[Newtonsoft.Json.JsonProperty]
internal string Property2 { get; set; }

It's worth noting that Json.NET is vastly more performant

50% faster than DataContractJsonSerializer, and 250% faster than JavaScriptSerializer.

and has far more configuration options and is currently the default choice by Microsoft for .NET.

Per your request in the comments, it IS possible to do this with a .NET FCL library if you use DataContractJsonSerializer, although that presents it's own set of pain in terms of the api and the need to mark every single class and property with [DataContract] and [DataMember] respectively.

using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

var instance = new MyClass {
        Property1 = "One",
        Property2 = "Twp",
        Property3 = "Three"
};

var ser = new DataContractJsonSerializer(instance.GetType());

using (MemoryStream ms = new MemoryStream())
{
    ser.WriteObject(ms, instance);
    string jsonData = Encoding.Default.GetString(ms.ToArray());
}

[DataContract]
public class MyClass
{
    [DataMember]
    public string Property1 { get; set; }
    [DataMember]
    internal string Property2 { get; set; }
    [DataMember]
    public string Property3 { get; set; }
}

This will correctly output

{"Property1":"One","Property2":"Twp","Property3":"Three"}

although I personally believe you're being dogmatic for zero value and creating a great deal of pain for yourself. I'd still highly recommend you switch to a more modern serializer.

Sign up to request clarification or add additional context in comments.

6 Comments

I am just curious to know about why don't it get supported in System.Web.Script.Serialization.JavaScriptSerializer. Is there any reason for not supporting it? Yeah, I can do it with Newtonsoft as you specified but for simple serialzation/deserailzation, I thought JavaScriptSerializer would be fine.
Because when Microsoft wrote it they didn't take it into account. You'd have to ask whoever wrote the serializer class :). That said, there's no reason to use JavaScriptSerializer anymore. It's deprecated, slow, inefficient and quirky. You should switch to a more modern serializer.
Do .NET FCL itself has any other way to serialize/deserialize internal properties?
Indeed, the app I've been developing is smaller(interms of size, my app : 10KB and Newtonsoft : 475KB) so I am hesitate to use third party library(Newtonsoft) to do simple serialization job. The question is just for my curiosity, otherwise your answer is really great.
I'd recommend a smaller serializer in that case then, if possible. Something like github.com/kevin-montrose/Jil might work well for you, although that might still be too large. It sounds like your perf concerns come in the way of total library size, not speed which means you might be stuck with DataContractJsonSerializer.
|
1

The documentation for JavaScriptSerializer is on the sparse side, I couldn't find anything about how that type deals with access modifiers.

internal hides Property2 from types outside your assembly, so I presume there is some code in JavaScriptSerializer that asks "What properties can I see on this object?"

That is a tricky question, as you've seen, and more robust serialization systems ask the better-documented question "What properties on this object are annotated with serialization hints?"

See JSON.net (as recommended in the JavaScriptSerializer docs) and DataContractJsonSerializer

3 Comments

Do .NET FCL itself has any other way to serialize/deserialize internal properties?
DataContractJsonSerializer should respect all properties tagged with DataMember regardless of their access modifier, IIRC.
Also, @LolCoder아카쉬 I get the desire to stick to things in the base classes. I've worked in situations where the effort to install libs on production quickly becomes greater than the effort to re-invent wheels from base classes.

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.