Multiple JSONproperty Name Assigned to Single Property

multiple JsonProperty Name assigned to single property

A simple solution which does not require a converter: just add a second, private property to your class, mark it with [JsonProperty("name2")], and have it set the first property:

public class Specifications
{
[JsonProperty("name1")]
public string CodeModel { get; set; }

[JsonProperty("name2")]
private string CodeModel2 { set { CodeModel = value; } }
}

Fiddle: https://dotnetfiddle.net/z3KJj5

Mapping multiple property names to the same field in Newtonsoft.JSON

You could use a custom ContractResolver in this answer:

Json.NET deserialize or serialize json string and map properties to different property names defined at runtime

Or

Use [JsonProperty("")] to look for different variations of the property name and return with one of the properties like this:

public class Message
{
private string _name;

[JsonProperty("Navn" )]
public string NorwegianName { get; set; }

[JsonProperty("Name")]
public string Name {
get { return _name ?? NorwegianName; }
set { _name = value; } }
}

This will return the name with JSON property name: Navn or Name.

Assign Multiple JsonProperties?

No, this is not possible.

Let's take a look at the Json.NET documentation. In particular the help page about the JsonPropertyAttribute class.

To quote:

"Instructs the JsonSerializer to always serialize the member with the specified name."

It's declared in the Newtonsoft.Json namespace. We need to determine how it is declared. Let's take a look at the Json.NET's source code on CodePlex:

http://json.codeplex.com/

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property |     
AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class JsonPropertyAttribute : Attribute
{
//...
}

Guess that answers the question. The AllowMultiple property of the attribute is set to false. So you can't decorate a property, field or parameter more than once with this attribute.

Even if you could how do you expect Json.net to figure out which attribute to use? I would create types for Twitter and Facebook separately into which you can deserialize the received JSON data.

So:

Twitter -> JSON -> Twitter specific types
Facebook -> JSON -> Facebook spefic types

Then create an abstraction which your application uses instead of addressing these types directly. They just belong to a specific social media implementation.

Twitter / Facebook / ... speficic types -> Your types

If you directly try to deserialize the data into your "common types", then you are just going to keep struggling because they don't align 100% with the received data and you'll wind up with some funky, hard to maintain deserialization logic.

Another option is to create your own custom Json.NET converter.

http://geekswithblogs.net/DavidHoerster/archive/2011/07/26/json.net-custom-convertersndasha-quick-tour.aspx

Just create a converter for Twitter and Facebook and when you deserialize the JSON data, just specify which converter you want to use.

  • TwitterConverter
  • FacebookConverter

E.g.:

MySocialType myType = JsonConvert.DeserializeObject<Mapped>(json, 
new TwitterConverter());

Anyway I would try to avoid polluting your class types with the deserialization logic itself.

How do I have two identical json property names assigned to two separated fields

One way you can achieve this is, using @JsonAnyGetter, Try this

public class TestDTO {

@JsonIgnore
List<String> paymentTransactionResponse;

@JsonIgnore
String paymentTransactionResponseError;

public List<String> getPaymentTransactionResponse() {
return paymentTransactionResponse;
}

public void setPaymentTransactionResponse(List<String> paymentTransactionResponse) {
this.paymentTransactionResponse = paymentTransactionResponse;
}

public String getPaymentTransactionResponseError() {
return paymentTransactionResponseError;
}

public void setPaymentTransactionResponseError(String paymentTransactionResponseError) {
this.paymentTransactionResponseError = paymentTransactionResponseError;
}

@JsonAnyGetter
public Map<String, Object> getData(){
Map<String, Object> map = new HashMap<String, Object>();
if(paymentTransactionResponse != null) {
map.put("paymentTransactionResponse", paymentTransactionResponse);
}else {
map.put("paymentTransactionResponse", paymentTransactionResponseError);
}
return map;
}}

Assign the same JsonProperty to two properties on class

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);
}


Related Topics



Leave a reply



Submit