为什么 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
我一直在序列化具有一些内部属性的自定义类型,但是在序列化时,似乎使用 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