从请求中反序列化JSON属性时,我想将它用于我对象的两个不同属性。 e.g;
public class Example
{
[JsonProperty(PropertyName = "favoriteColor")]
public string favoriteColor { get; set; }
[JsonProperty(PropertyName = "favoriteColor")]
public string oldFavoriteColor { get; set; }
}
然而,这会导致错误:
名为' favoriteColor'的成员已经存在'示例'。使用JsonPropertyAttribute指定另一个名称。
如果这正是我想要的,我该怎么做?
答案 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);
}