将相同的JsonProperty分配给类上的两个属性

时间:2018-01-05 18:35:21

标签: c# json json.net

从请求中反序列化JSON属性时,我想将它用于我对象的两个不同属性。 e.g;

public class Example
{
    [JsonProperty(PropertyName = "favoriteColor")]
    public string favoriteColor { get; set; }

    [JsonProperty(PropertyName = "favoriteColor")]
    public string oldFavoriteColor { get; set; }
}

然而,这会导致错误:

  

名为' favoriteColor'的成员已经存在'示例'。使用JsonPropertyAttribute指定另一个名称。

如果这正是我想要的,我该怎么做?

2 个答案:

答案 0 :(得分:1)

我认为您可以修改其中一个属性的set方法,这样无论何时设置它,它还会设置其他属性

e.g。

public class Example
{
    [JsonProperty(PropertyName = "favoriteColor")]
    public string favoriteColor { 
      get { return favoriteColor; } ; 
      set
      {
        favoriteColor = value;
        if (oldFavoriteColor == null) {
          oldFavoriteColor = value;
        }
      }
    }

    public string? oldFavoriteColor { get; set; }
}

答案 1 :(得分:0)

可能有一个更好的答案,包括从问题中退一步,看看是否有完全不同的方法。特别是,为什么需要一个具有两个具有相同值的属性的类?除了从JSON反序列化之外,此类的每个其他使用者都知道这两个属性需要保持同步,为什么?

但这回答了当前的问题。

[JsonProperty]属性用于序列化和反序列化。如果您有两个具有相同[JsonProperty]属性的属性,那么当您将对象序列化为JSON时,您将拥有两个具有相同名称的属性。

您可以像这样创建自定义JSON序列化程序。如您所见,在反序列化Example后,它将使用favoriteColor属性的值填充oldFavoriteColor属性。

public class ExampleConverter : CustomCreationConverter<Example>
{
    public override Example Create(Type objectType)
    {
        return new Example();
    }

    public override object ReadJson(JsonReader reader, Type objectType, 
        object existingValue, JsonSerializer serializer)
    {
        var result = (Example)base.ReadJson(reader, objectType, existingValue, 
            serializer);
        result.favoriteColor = result.oldFavoriteColor;
        return result;
    }
}

为了使其工作,您还必须告诉序列化程序不要尝试反序列化favoriteColor属性。即使没有[JsonProperty]属性,[JsonProperty(PropertyName = "favoriteColor")]与另一个实际命名为&#34; favoriteColor的属性之间仍存在冲突。&#34;

public class Example
{
    [JsonIgnore]
    public string favoriteColor { get; set; }

    [JsonProperty(PropertyName = "favoriteColor")]
    public string oldFavoriteColor { get; set; }
}

确认的单元测试:

public void DeserializerPopulatesFavoriteColorFromOldFavoriteColor()
{
    var json = @"{ favoriteColor: ""Green""}";
    var deserialized = JsonConvert.DeserializeObject<Example>(json, new ExampleConverter());
    Assert.AreEqual("Green", deserialized.oldFavoriteColor);
    Assert.AreEqual(deserialized.oldFavoriteColor, deserialized.favoriteColor);
}