使用Json.NET在通用类中序列化受保护的属性

时间:2015-10-05 17:13:14

标签: c# json serialization json.net

我正在尝试序列化一个由许多继承自IMyDataType的变量组成的类。

public abstract class IMyDataType<T>
{
    protected virtual T Data { get; set; }
    public abstract String ToString(String args = null);
    public abstract Boolean SetValue(T newValue);
    public abstract Boolean CheckValue(T newValue);
    public abstract T GetValue();
}

例如,我可能有一个班级MyInteger

public class MyInteger : IMyDataType<int>
{
    public int Min { get; protected set; }
    public int Max { get; protected set; }
    protected override int Data { get; set; }

    public MyInteger(int value)
    {
        Min = int.MinValue;
        Max = int.MaxValue;
        if (!SetValue(value))
            Data = 0;
    }

    public MyInteger(int min, int value, int max)
    {
        Min = min;
        Max = max;
        if (!SetValue(value))
            Data = 0;
    }

    public override Boolean SetValue(int newVal)
    {
        if (newVal >= Min && newVal <= Max)
        {
            Data = newVal;
            return true;
        }
        return false;
    }

    public override Boolean CheckValue(int newVal)
    {
        return (newVal >= Min && newVal <= Max);
    }

    public override int GetValue() { return Data; }
    public override String ToString(String args = null) { return Data.ToString(args); }
}

每当我尝试序列化IMyDataType的子类时,变量T Data从未被序列化,但MinMax是。要将T Data序列化,我需要做些什么?

编辑:根据DotNetom的回答,我将T Data的访问修饰符更改为public,这允许将其序列化。虽然,它有理由受到保护。有没有其他方法可以在保持其访问修饰符完整的同时序列化它?

2 个答案:

答案 0 :(得分:3)

默认情况下,Json.NET仅使用公共getter序列化属性(请参阅docs)。您的房产数据受到保护:

"0p

为了将其序列化,您应该将其更改为public:

protected virtual T Data { get; set; }

如果无法更改对公共的访问权限,则可以通过实施自定义合同解析程序来序列化非公共项目。关于如何使用它们的样本可以在SO的问题答案中找到 - JSON.Net: Force serialization of all private fields and all fields in sub-classes

答案 1 :(得分:3)

您只需为Data创建备用私有属性获取器,并使用[JsonProperty]属性进行标记。这将允许Json.Net“看到”它并将其序列化,而无需更改原始属性的访问修饰符。

public abstract class IMyDataType<T>
{
    protected virtual T Data { get; set; }
    ...

    [JsonProperty("Value")]
    private T AlternateData
    {
        get { return Data; }
    }
}

小提琴:https://dotnetfiddle.net/0JMZzX

(注意:理论上,您可以使用Data属性标记受保护的[JsonProperty]属性本身,而不是创建备用属性getter。但是,这似乎只有在基本属性为在子类中没有重写。一旦覆盖它,该属性由于某种原因不再起作用 - 即使你将属性移动到子类或将它放在基类和子类中。我不确定这是否是一个Json.Net中的错误或故意的。使用替代的getter似乎总是起作用。)