Assign Multiple JsonProperties?

11,482

Solution 1

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.

Solution 2

I think I solved it in the easiest way possible.....

    public string id_str { 
        get{return id;}
        set{id = id_str;}
    }

    public string id { get; set; }

Simply added both and made the one, set the other.. It works :P Sometimes simple solutions are the best?

Solution 3

If you are looking for a generic class model to consume, you can do it as follows.

public class GenericClass
{
    public virtual string ID {get;set;}
}
public class FaceBook : GenericClass
{
    [JsonProperty("id")]
    public override string ID { get => base.ID; set => base.ID = value; }
}
public class Twitter : GenericClass
{
    [JsonProperty("id_str")]
    public override string ID { get => base.ID; set => base.ID = value; }
}

For Facebook,

GenericClass genericClass = JsonConvert.DeserializeObject<FaceBook>(json);

Fot Twitter,

GenericClass genericClass = JsonConvert.DeserializeObject<Twitter>(json);

and you can forget what model class is used, and just use GenericClass

Share:
11,482

Related videos on Youtube

Sjaak van der Heide
Author by

Sjaak van der Heide

Hey folks, I am Sjaak, I am currently working as an intern at VincisAction in Sneek. I'm mainly working in C#/ASP.NET at the moment, but have used several other languages in the past including: Delphi/VB, Java, C++, PHP. I wouldn't call myself a superdeveloper (yet), but then again a man can't know everything can he.

Updated on September 18, 2022

Comments

  • Sjaak van der Heide
    Sjaak van der Heide over 1 year

    I am trying to make a single dataclass that holds information from both Facebook and Twitter.

    but in my JSON reply from twitter I need id_str and from FaceBook I get id.

    I need those two to be put into the id-string.

    Now I know I can use [JsonProperty("id_str")] if I want to deserialize Twitters id_str into my id-string.

    But what if I need both Facebook's id and Twitters id_str to be deserialized in the same id-string I have in my dataclass?

  • Sjaak van der Heide
    Sjaak van der Heide almost 12 years
    Well, I was hoping it would just check for either one of them and use the one that is not null. Guess I'll need to come up with something else... Thanks anyway! :)
  • Christophe Geers
    Christophe Geers almost 12 years
    Will work, but kinds of pollutes your type with all sort of properties. Half of which are never used depending on which JSON you deserialized.
  • Sjaak van der Heide
    Sjaak van der Heide almost 12 years
    indeed, but it will at least allow me to test my theory before doing it the proper way :)