【问题标题】:JSON Serializer object with internal properties具有内部属性的 JSON 序列化器对象
【发布时间】:2014-11-11 20:18:02
【问题描述】:

我有一些内部属性的类,我也想将它们序列化为 json。我怎样才能做到这一点? 例如

public class Foo
{
    internal int num1 { get; set; }
    internal double num2 { get; set; }
    public string Description { get; set; }

    public override string ToString()
    {
        if (!string.IsNullOrEmpty(Description))
            return Description;

        return base.ToString();
    }
}

使用保存它

Foo f = new Foo();
f.Description = "Foo Example";
JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All };

 string jsonOutput = JsonConvert.SerializeObject(f, Formatting.Indented, settings);

 using (StreamWriter sw = new StreamWriter("json_file.json"))
 {
     sw.WriteLine(jsonOutput);
 }

我明白了

{  
"$type": "SideSlopeTest.Foo, SideSlopeTest",
"Description": "Foo Example"
}

【问题讨论】:

  • 通常内部属性不打算离开当前程序集的边界并因此被序列化。为什么你需要这样做?如果您想要一个正确的 JSON 表示,您可能需要一个 DTO 来将您的内部/私有内容映射到然后序列化。
  • +1 @DarinDimitrov 所说的。但如果你真的想这样做,我相信你需要继承 DefaultContractResolver 以使其也可以查看非公共属性。
  • 只需用[JsonProperty()] 属性标记它们。
  • 如果类也是内部的,用[JsonObject()]标记它

标签: c# .net json


【解决方案1】:

[JsonProperty]属性标记要序列化的内部属性:

public class Foo
{
    [JsonProperty]
    internal int num1 { get; set; }
    [JsonProperty]
    internal double num2 { get; set; }

    public string Description { get; set; }

    public override string ToString()
    {
        if (!string.IsNullOrEmpty(Description))
            return Description;

        return base.ToString();
    }
}

然后再进行测试:

Foo f = new Foo();
f.Description = "Foo Example";
f.num1 = 101;
f.num2 = 202;
JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All };

var jsonOutput = JsonConvert.SerializeObject(f, Formatting.Indented, settings);

Console.WriteLine(jsonOutput);

我得到以下输出:

{
  "$type": "Tile.JsonInternalPropertySerialization.Foo, Tile",
  "num1": 101,
  "num2": 202.0,
  "Description": "Foo Example"
}

(其中“Tile.JsonInternalPropertySerialization”和“Tile”是我正在使用的命名空间和程序集名称)。

顺便说一句,在使用TypeNameHandling 时,请注意Newtonsoft docs 的注意事项:

当您的应用程序从外部源反序列化 JSON 时,应谨慎使用 TypeNameHandling。使用 None 以外的值反序列化时,应使用自定义 SerializationBinder 验证传入类型。

关于为什么这可能是必要的讨论,请参阅 TypeNameHandling caution in Newtonsoft JsonExternal json vulnerable because of Json.Net TypeNameHandling auto?

【讨论】:

  • 我刚刚删除了我的回答,说内部属性在程序集之外无法访问,因为这对我来说是新闻。序列化程序如何跨程序集访问这些?这不是一个安全问题吗?
  • @esmoore68 - 序列化程序使用反射。参见例如stackoverflow.com/questions/1565734/…stackoverflow.com/questions/30191282/….
  • 除了@dbc 回答之外,报告的内容对于内部可见性类和私有可见性(嵌套)类仍然有效
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-27
  • 1970-01-01
  • 1970-01-01
  • 2012-12-23
相关资源
最近更新 更多