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

C# 将相同的JsonProperty分配给类上的两个属性,c#,json,json.net,C#,Json,Json.net,当从请求反序列化JSON属性时,我希望将其用于对象上的两个不同属性。e、 g public class Example { [JsonProperty(PropertyName = "favoriteColor")] public string favoriteColor { get; set; } [JsonProperty(PropertyName = "favoriteColor")] public string oldFavoriteColor { ge

当从请求反序列化JSON属性时,我希望将其用于对象上的两个不同属性。e、 g

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

    [JsonProperty(PropertyName = "favoriteColor")]
    public string oldFavoriteColor { get; set; }
}
但是,这会导致错误:

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


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

我认为您可以修改其中一个属性的set方法,以便无论何时设置,它都可以设置另一个属性

e、 g


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

但这回答了眼前的问题

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

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

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;
    }
}
单元测试,以确认:

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);
}
public void反序列化器populateFavoriteColorFromoldFavoriteColor()
{
var json=@“{favoriteColor:“绿色”}”;
var deserialized=JsonConvert.DeserializeObject(json,新的ExampleConverter());
AreEqual(“绿色”,反序列化.oldFavoriteColor);
Assert.AreEqual(反序列化的.oldFavoriteColor,反序列化的.favoriteColor);
}

Set的修改可能会过火。它可能有不必要的副作用。JSON是一种序列化方法。因此,在这里提供自定义序列化/反序列化函数可能更好。这完全超出了自动装置能为您做的范围。在这种特定情况下(颜色和旧颜色),它可能会起作用。但我更喜欢将其设置为none/other特定值,表示没有设置它。出于好奇,我尝试了另一种方法,即自定义序列化程序。此解决方案(修改
)a)使用更少的代码行,b)确保属性实际上保持同步。对我来说,根本的问题是有两个值相同的属性。如果未来的开发人员看到两个几乎相同的属性,他们会浪费时间猜测使用哪一个,或者在代码中寻找它们是如何填充的,这肯定会让他们感到困惑如果传入属性是
color
,而不是目标对象上存在的属性;然后,
favoriteColor
oldFavoriteColor
可以有自己的
CustomCreationConverter
s,它应该可以工作吗?如果您有一个名为“favoriteColor”的属性,然后有一个不同名称的属性,但具有属性
[JsonProperty(PropertyName=“favoriteColor”)]
,你会得到与你的问题相同的错误。为了使用自定义转换器,您首先必须消除这些问题。您不能有竞争/冲突的属性名称和属性。一旦你把那个部分整理好,你就可以在自定义转换器中做任何你想做的事情。
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);
}