Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assign Multiple JsonProperties?

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?

like image 551
Sjaak van der Heide Avatar asked Jun 26 '12 08:06

Sjaak van der Heide


2 Answers

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?

like image 102
Sjaak van der Heide Avatar answered Sep 21 '22 15:09

Sjaak van der Heide


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.

like image 28
Christophe Geers Avatar answered Sep 22 '22 15:09

Christophe Geers