为什么我不能序列化具有私有 setter 的 属性(C#,json)
Why cant I serialize a property that has a private setter (C#, json)
我正在使用 dotnet core 2.1 并制作了一个助手来从 JSON 序列化和序列化到 JSON。
它建立在 System.Runtime.Serialization.Json 上,随 dotnet 核心一起提供。
出于某些原因我不想使用JSON.NET lib(这里无关紧要)
我遇到了一个我不明白的错误,
这是我制作的 Helper class(我刚刚离开了 ToJson 方法,因为这是我出现问题的地方)
public static class JsonUtils
{
private static readonly DataContractJsonSerializerSettings _jsonSettings = new DataContractJsonSerializerSettings
{
UseSimpleDictionaryFormat = true,
SerializeReadOnlyTypes = true,
EmitTypeInformation = EmitTypeInformation.Never
};
public static string ToReadableJson<T>(T o)
{
string res = null;
try
{
using (var ms = new MemoryStream())
using (var writer = JsonReaderWriterFactory.CreateJsonWriter(ms, Encoding.UTF8, true, true, " "))
{
var serializer = new DataContractJsonSerializer(typeof(T), _jsonSettings);
serializer.WriteObject(writer, o);
writer.Flush();
ms.Position = 0;
using (var sr = new StreamReader(ms))
{
res = sr.ReadToEnd();
}
}
}
catch
{ }
return res;
}
}
一切正常,直到我最近注意到一些对象如果它们的属性 非 public setter 就会被简单地忽略。我不明白为什么setter必须是public,它只是应该读取数据来序列化,对吗?
这里有一些测试代码:
public class TestSubObject
{
public string Property { get; set; } = "Bar";
}
public class TestObject
{
public TestSubObject Sub { get; set; }
public string Property { get; set; }
}
class Program
{
static void Main(string[] args)
{
var o = new TestObject
{
Property = "Foo",
Sub = new TestSubObject()
};
string json = JsonUtils.ToReadableJson<TestObject>(o);
Console.WriteLine(json);
Console.Read();
}
}
在这个例子中,我只有一个根对象 (TestObject),它有另一个复杂对象 属性 (TestSubObject)
在这种情况下,它有效:
然后,如果我将 TestSubObject.Property setter 从 public 更改为私有,它就不再起作用了。 (在我的真实情况下,class 在另一个设置了 'internal' 的程序集中)
我的子 属性 消失了。
如您所见,我检查了 DataContractJsonSerializerSettings 并已将 SerializeReadOnlyTypes 设置为 true,但这并没有改变任何内容。
是的,我可以编辑我的 classes 以使其完整 public 但我不明白这一点,所以我 post 在这里,如果有人有想法的话。
谢谢
当您在没有任何注释的情况下使用 System.Runtime.Serialization
时,它将忽略无法设置的属性并序列化给定类型的所有 public 可以序列化和反序列化的成员。
但是,如果您明确声明应序列化的内容,它将起作用:
[DataContract]
public class TestSubObject
{
[DataMember]
public string Property { get; private set; } = "Bar";
}
[DataContract]
public class TestObject
{
[DataMember]
public TestSubObject Sub { get; set; }
[DataMember]
public string Property { get; set; }
}
输出:
{
"Property": "Foo",
"Sub": {
"Property": "Bar"
}
}
我正在使用 dotnet core 2.1 并制作了一个助手来从 JSON 序列化和序列化到 JSON。 它建立在 System.Runtime.Serialization.Json 上,随 dotnet 核心一起提供。
出于某些原因我不想使用JSON.NET lib(这里无关紧要)
我遇到了一个我不明白的错误, 这是我制作的 Helper class(我刚刚离开了 ToJson 方法,因为这是我出现问题的地方)
public static class JsonUtils
{
private static readonly DataContractJsonSerializerSettings _jsonSettings = new DataContractJsonSerializerSettings
{
UseSimpleDictionaryFormat = true,
SerializeReadOnlyTypes = true,
EmitTypeInformation = EmitTypeInformation.Never
};
public static string ToReadableJson<T>(T o)
{
string res = null;
try
{
using (var ms = new MemoryStream())
using (var writer = JsonReaderWriterFactory.CreateJsonWriter(ms, Encoding.UTF8, true, true, " "))
{
var serializer = new DataContractJsonSerializer(typeof(T), _jsonSettings);
serializer.WriteObject(writer, o);
writer.Flush();
ms.Position = 0;
using (var sr = new StreamReader(ms))
{
res = sr.ReadToEnd();
}
}
}
catch
{ }
return res;
}
}
一切正常,直到我最近注意到一些对象如果它们的属性 非 public setter 就会被简单地忽略。我不明白为什么setter必须是public,它只是应该读取数据来序列化,对吗?
这里有一些测试代码:
public class TestSubObject
{
public string Property { get; set; } = "Bar";
}
public class TestObject
{
public TestSubObject Sub { get; set; }
public string Property { get; set; }
}
class Program
{
static void Main(string[] args)
{
var o = new TestObject
{
Property = "Foo",
Sub = new TestSubObject()
};
string json = JsonUtils.ToReadableJson<TestObject>(o);
Console.WriteLine(json);
Console.Read();
}
}
在这个例子中,我只有一个根对象 (TestObject),它有另一个复杂对象 属性 (TestSubObject)
在这种情况下,它有效:
然后,如果我将 TestSubObject.Property setter 从 public 更改为私有,它就不再起作用了。 (在我的真实情况下,class 在另一个设置了 'internal' 的程序集中)
我的子 属性 消失了。
如您所见,我检查了 DataContractJsonSerializerSettings 并已将 SerializeReadOnlyTypes 设置为 true,但这并没有改变任何内容。
是的,我可以编辑我的 classes 以使其完整 public 但我不明白这一点,所以我 post 在这里,如果有人有想法的话。
谢谢
当您在没有任何注释的情况下使用 System.Runtime.Serialization
时,它将忽略无法设置的属性并序列化给定类型的所有 public 可以序列化和反序列化的成员。
但是,如果您明确声明应序列化的内容,它将起作用:
[DataContract]
public class TestSubObject
{
[DataMember]
public string Property { get; private set; } = "Bar";
}
[DataContract]
public class TestObject
{
[DataMember]
public TestSubObject Sub { get; set; }
[DataMember]
public string Property { get; set; }
}
输出:
{
"Property": "Foo",
"Sub": {
"Property": "Bar"
}
}