为什么我不能序列化具有私有设置程序(C#,json)的属性

时间:2019-05-18 20:05:06

标签: c# json .net-core datacontractjsonserializer

我正在使用dotnet core 2.1,并提供了一个帮助程序从JSON序列化到JSON。 它基于dotnet核心随附的System.Runtime.Serialization.Json构建。

出于某些原因,我不想使用JSON.NET库(在这里无关紧要)

我遇到了一个我不了解的错误, 这是我创建的Helper类(我刚刚离开了ToJson方法,因为这是发生问题的那个方法)

name

一切正常,直到最近我注意到,如果某些对象的属性具有非公共设置器,它们将被忽略。我不明白为什么setter必须公开,只是应该读取数据进行序列化,对吧?

这里有一些代码需要测试:

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

在此示例中,我只有一个根对象(TestObject),该对象具有另一个复杂对象作为属性(TestSubObject)

在这种情况下,它可以工作:

OK

然后,如果我将TestSubObject.Property设置器从公共更改为私有,它将不再起作用。 (在我的实际情况下,该类在另一个具有“内部”设置的程序集中)

NOTOK

我的子财产消失了。

如您所见,我检查了DataContractJsonSerializerSettings并已将SerializeReadOnlyTypes设置为true,但这并没有任何改变。

是的,我可以将我的班级编辑为完全公开的,但我不明白这一点,所以如果有人有主意,我可以将其发布在这里。

谢谢

1 个答案:

答案 0 :(得分:3)

当您使用System.Runtime.Serialization而没有任何注释时,它将忽略无法设置的属性,并序列化可以序列化和反序列化的给定类型的所有公共成员。

但是,如果您要明确声明应序列化的内容,它将起作用:

[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"
  }
}