为Json.NET中的其他属性指定属性的默认值 [英] Specifying default value for a property in relation to other property in Json.NET

查看:106
本文介绍了为Json.NET中的其他属性指定属性的默认值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有一种方法可以相对于Json.NET中相同类的其他属性来设置属性的默认值,例如:

I am wondering if there is a way to set default value for a property in relation to other property of the same class in Json.NET e.g like this:

public class JsonsoftExample
{
    [JsonProperty(Required = Required.Always)]
    public DateTime Start { get; set; }

    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
    [DefaultValue(Start.AddHours(1))]
    public DateTime End { get; set; }
}

我要在此处完成的工作是,在例如反序列化的情况下,用 DateTime 值填充 End ,该值比 Start 晚一小时. JSON到域模型,并且 End 值丢失或为空.像这样:

What I am trying to accomplish here is to populate End with DateTime value that is one hour later than Start in cases e.g when deserializing json to domain model and End value is missing or null. Like this:

string json = "{\"Start\": \"2017-01-01T08:00:00+01:00\"}";
var deserialized = JsonConvert.DeserializeObject<JsonsoftExample>(json);

我现在做的方式是稍后在代码中检查域对象中的 End 值是否为空,以及是否将其填充为所需的值.

The way I am doing it now is just inspecting later in code if End value is null in my domain object and if it is - populating it with desired value.

代码示例中提出的方法是否可行?或者,除了上面段落中的手动检查之外,还有没有更好的简单方法?

Is it feasible the way proposed in code sample or is there maybe a better simpler way except for the manual checking as in paragraph above?

推荐答案

JSON标准中所指定,JSON对象是一组 无序名称/值对,因此,一般而言,Json.NET不允许相对于另一属性设置一个属性. Json.NET是一个流式单遍解串器,并且不能保证它会首先出现在JSON中.

As specified in the JSON standard, a JSON object is an unordered set of name/value pairs, so in general Json.NET does not allow one property to be set relative to another. Json.NET is a streaming, single-pass deserializer and there's no guarantee which will appear first in the JSON.

但是,当您的对象通过例如

However, when your object specifies use of a parameterized constructor via, e.g., the [JsonConstructor] attribute, Json.NET will pre-load the JSON properties and their values then construct the object with the deserialized values. This affords an opportunity to set the End property relative to the Start property:

public partial class JsonsoftExample
{
    public JsonsoftExample() { }

    [JsonConstructor]       
    JsonsoftExample(DateTime start, DateTime? end)
    {
        this.Start = start;
        this.End = end ?? Start.AddHours(1);            
    }

    [JsonProperty(Required = Required.Always)]
    public DateTime Start { get; set; }

    public DateTime End { get; set; }
}

注意:

  • 构造函数参数的名称必须与属性的名称以模数形式相同.这就是Json.NET如何将构造函数参数与JSON属性进行匹配.

  • The names of the constructor arguments must be the same as the names of the properties, modulo case. This is how Json.NET matches constructor arguments with JSON properties.

请注意,End属性的类型为DateTime,而end构造函数的参数类型为DateTime?.当JSON中缺少"End"时,Json.NET会将null值传递到构造函数中,可以检查该值以正确初始化相对于StartEnd时间.

Note that the End property is of type DateTime while the end constructor argument is of type DateTime?. When "End" is missing from the JSON, Json.NET will pass in a null value into the constructor, which can be checked for to properly initialize the End time relative to the Start.

如果您不想在开始时间恰好一个小时后序列化End属性,则可以使用

If you don't want to serialize the End property when it is exactly one hour later than the start, you can use conditional property serialization:

public bool ShouldSerializeEnd()
{
    return End != Start.AddHours(1);
}

  • 标记为[JsonConstructor]的构造函数不需要为公共的.未传递给构造函数的属性将在构建后按照常规反序列化进行填充.

  • The constructor does not need to be public when marked with [JsonConstructor]. Properties not passed into the constructor will be populated after construction as per usual deserialization.

    示例小提琴.

    这篇关于为Json.NET中的其他属性指定属性的默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆