为什么 JavaScriptSerializer 不能序列化内部属性?

why can't JavaScriptSerializer serialize internal properties?

我一直在序列化具有一些内部属性的自定义类型,但是在序列化时,似乎使用 System.Web.Script.Serialization.JavaScriptSerializer serialize 方法不会序列化内部属性(因为它跳过了内部 属性 在序列化字符串中)。 从以下代码和输出中可以很容易地理解它:

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

jsonString 具有以下值:

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

在输出中,您可以看到序列化字符串没有内部 属性 的 Property2。在序列化中不支持内部 属性 有什么逻辑吗?

序列化内部 属性 的解决方法是什么(除了将内部更改为 public 修饰符)?

System.Web.Script.Serialization.JavaScriptSerializer根本不支持它。

我建议您切换到 Json.NET。在这种情况下,您需要做的就是用 json 属性 属性标记内部 属性,它会被 Json.NET 序列化程序拾取。

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

值得注意的是 Json.NET 的性能要好得多

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

并且有更多的配置选项,目前是 Microsoft .NET 的默认选择。

根据您在评论中的要求,如果您使用 DataContractJsonSerializer,则可以使用 .NET FCL 库执行此操作,尽管就 api 而言,这会带来一系列痛苦并且需要分别用 [DataContract][DataMember] 标记每个 class 和 属性。

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

这将正确输出

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

虽然我个人认为你是教条主义的零价值,给自己制造了很大的痛苦。我仍然强烈建议您切换到更现代的序列化程序。

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

internal 从程序集外部的类型中隐藏 Property2,所以我假设 JavaScriptSerializer 中有一些代码询问 "What properties can I see on this object?"

如您所见,这是一个棘手的问题,更强大的序列化系统会提出更好记录的问题 "What properties on this object are annotated with serialization hints?"

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