【发布时间】:2014-03-20 22:44:45
【问题描述】:
我注意到,默认情况下,JSON.NET 只会(反)序列化对象的公共属性。这很好。但是,当属性被标记为 [JsonPropertyAttribute] 时,JSON.NET 也将访问 private getter 和 setter。这很糟糕。
我想要解决这个问题的方法是用 [JsonIgnoreAttribute] 标记私有 getter/setter。
例如:
public class JsonObject
{
[JsonProperty(PropertyName = "read_write_property")]
public object ReadOnlyProperty
{
get;
[JsonIgnore] private set;
}
}
很遗憾,这不是有效的 C# 代码。那么什么代码可以达到同样的效果呢?
我知道一些可行的想法:
- 移除 [JsonPropertyAttribute]
- 完全移除 setter 并引入支持字段
只有这两个选项吗?
编辑
我为我的只读属性添加了支持字段。不确定,但我想我在 Json.Net 中发现了一个错误。当仅存在 getter 时,即使指定的 name 属性与 JSON 字符串匹配,序列化程序也会将该属性视为不存在。这特别烦人,因为我也在使用[JsonExtensionData] 机制。所以反序列化的值最终会进入我的扩展数据字典。下面是演示问题的代码:
违规班级
using System.ComponentModel;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public class JsonObject
{
private readonly BindingDirection bindingDirection;
public JsonObject()
{
this.bindingDirection = BindingDirection.OneWay;
}
[JsonProperty(PropertyName = "binding_type"), JsonConverter(typeof(StringEnumConverter))]
public BindingDirection BindingDirection
{
get
{
return this.bindingDirection;
}
}
[JsonExtensionData]
public IDictionary<string, object> ExtensionData { get; set; }
}
演示
using Newtonsoft.Json;
class Program
{
static void Main(string[] args)
{
var obj = new JsonObject();
var serialized = JsonConvert.SerializeObject(obj);
var deserialized = JsonConvert.DeserializeObject<JsonObject>(serialized);
Console.WriteLine("*** Extension data ***\n");
foreach (var kvp in deserialized.ExtensionData)
{
Console.WriteLine("{0} == {1}", kvp.Key, kvp.Value);
}
Console.ReadLine();
}
}
输出
*** 扩展数据***
binding_type == OneWay
【问题讨论】:
-
您实际上想要达到什么结果?如果您有一个带有私有 setter 的公共字段,您是说您希望该字段序列化但不反序列化?
-
@BrianRogers,是的。我只希望将该属性序列化为 JSON。该属性是从构造函数初始化的(示例中未显示),因此我不必从 JSON 字符串中检索它。
-
但最重要的是,我只是希望 JSON.NET 不再违反面向对象编程最基本的原则之一!