为什么我不能序列化具有私有 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"
  }
}