Reputation: 10834
When deserializing a JSON property from a request I want to use it for two different properties on my object. e.g;
public class Example
{
[JsonProperty(PropertyName = "favoriteColor")]
public string favoriteColor { get; set; }
[JsonProperty(PropertyName = "favoriteColor")]
public string oldFavoriteColor { get; set; }
}
However this causes an error:
A member with the name 'favoriteColor' already exists on 'Example'. Use the JsonPropertyAttribute to specify another name.
How do I do this when that's exactly what I intend?
Upvotes: 1
Views: 3714
Reputation: 450
I think you could modify the set method for one of the properties so that whenever it is set, it also sets the other property
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; }
}
Upvotes: 2
Reputation: 29222
There may be a better answer that involves taking a step back from the problem and seeing whether there's a totally different approach. In particular, why do you need a class that has two properties with the same value? Other than deserializing from JSON, will every other consumer of this class know that these two properties need to be kept in sync, and why?
But this answers the immediate question.
The [JsonProperty]
attribute is used for both serializing and deserializing. If you had two properties with the same [JsonProperty]
attribute then when you serialized the object to JSON you would have two properties with the same name.
You can create a custom JSON serializer like this. As you can see, after an Example
is deserialized it will populate the favoriteColor
property with the value of the oldFavoriteColor
property.
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;
}
}
In order for this to work you also have to tell the serializer not to attempt to deserialize the favoriteColor
property. Even without the [JsonProperty]
attribute there's still a conflict between [JsonProperty(PropertyName = "favoriteColor")]
and another property actually named "favoriteColor."
public class Example
{
[JsonIgnore]
public string favoriteColor { get; set; }
[JsonProperty(PropertyName = "favoriteColor")]
public string oldFavoriteColor { get; set; }
}
A unit test to confirm:
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);
}
Upvotes: 0