【问题标题】:Json.net getter property not serializedJson.net getter 属性未序列化
【发布时间】:2012-04-01 10:32:51
【问题描述】:

我已经开始使用 json.net 来生成更好的 DateTimes,但是我注意到我的一个属性没有被序列化。它没有 setter,它的 getter 依赖于对象的另一个成员,例如

public int AmountInPence { get; set;}
public decimal AmountInPounds { get { return (decimal)AmountInPence / 100;  } }

我创建了一个继承自JsonResult 的类,主线是:

string serializedObject = JsonConvert.SerializeObject(Data, new IsoDateTimeConverter());

谁能告诉我如何强制它序列化该属性?

编辑: 只是为了澄清 - 这是一个简化的例子。我已经更新它以反映我首先将 int 转换为十进制。我之前忘记检查了,但该属性是部分类的一部分,因为它是从 WCF 服务返回的。我在我的程序集中声明了该属性,所以这可能是一个线索吗?

【问题讨论】:

    标签: c# asp.net-mvc json serialization json.net


    【解决方案1】:

    Json.net 没有任何问题。它可以很好地序列化只读属性。 问题出在你的AmountInPounds

    public decimal AmountInPounds { get { return AmountInPence / 100;  } }
    

    因为您正在使用 / 100 进行整数除法,这意味着如果 AmountInPence 小于 100,您将得到 0

    您需要使用m suffix 将100 标记为decimal

    public decimal AmountInPounds { get { return AmountInPence / 100m;  } }
    

    AmountInPounds 中获得正确的结果。

    在 cmets 之后编辑:

    计算出的属性 AmountInPounds在 WCF 服务生成的 DataContract 的部分类中

    DataContract 中,如果一个属性没有用DataMemberAttribute 标记,它似乎不会被序列化。

    所以除了 OP 的回答:

    [JsonPropertyAttribute(DefaultValueHandling = DefaultValueHandling.Include)]
    public decimal AmountInPounds { get { return (decimal)AmountInPence / 100;  } }
    

    这也是可行的:

    [System.Runtime.Serialization.DataMemberAttribute()]
    public decimal AmountInPounds { get { return (decimal)AmountInPence / 100; } }
    

    【讨论】:

    • 感谢您的回复。我不认为是因为这个(我已经编辑了我的问题)
    • 好的,那么您应该提供更多上下文。 Data 是什么您要序列化的内容?输出是什么?因为正如@StriplingWarrior 也指出:JsonConvert 序列化AmountInPounds...
    • Data 是一个对象 - JsonResult 的一个属性。一定要先投吗?
    • 不,你不需要投射。我认为问题出在部分类上......你能发布一个简化但可重现的代码吗?使用 partials 正确的命名空间等。因为它也应该使用 partials...
    • 刚刚意识到我不能在这样的只读属性上使用该属性:它需要是 [System.Runtime.Serialization.DataMemberAttribute()] public decimal AmountInPounds { get { return (decimal)AmountInPence / 100; } internal set { } } 这有点像 hack。你能更新你的答案吗?
    【解决方案2】:

    好的,看起来我已经找到了答案,很抱歉没有在帖子中提供更多细节,但我认为这最终并不重要。

    我需要在 AmountInPounds 属性上添加一个属性:

    [JsonPropertyAttribute(DefaultValueHandling = DefaultValueHandling.Include)]
    public decimal AmountInPounds { get { return (decimal)AmountInPence / 100;  } }
    

    【讨论】:

    • 很高兴您找到了解决方案,但仍然很奇怪。因为我无法通过部分类或继承或可以为空的属性来重现您的问题。 Newtonsoft.Json version 4.0.8 始终包含只读属性...
    • 是的,我创建了一个单独的解决方案来复制除 WCF 服务创建的类之外的所有内容,并且它按预期工作。也许该类上有一个属性会阻止 Json.Net 自动序列化那些只读属性。感谢您的宝贵时间!
    • 看来DataMemberAttribute 也解决了你的问题,我不知道为什么这可能是Json.net 中的一个错误。不过,我也用此信息更新了我的答案。
    • 可能是因为标准 JavaScriptSerializer 使用的类上有属性,所以属性上不需要它,但如果 Json.Net 不使用它们,那么这就是它停止工作的原因。 Anyhoo 我已将您的答案标记为已接受