2012-06-26 3 views
13

Я пытаюсь сделать один dataclass, который хранит информацию как от Facebook, так и от Twitter.Назначить несколько JsonProperties?

но в моем ответе JSON из twitter мне нужно id_str и из FaceBook я получаю id.

Мне нужно, чтобы эти два были помещены в строку id.

Теперь я знаю, что могу использовать [JsonProperty("id_str")], если я хочу десериализовать Twitters id_str в мой id -string.

Но что делать, если мне нужны оба Facebook id и Twitters id_str для десериализации в том же id -string У меня в моем dataclass?

ответ

7

Нет, это невозможно.

Давайте посмотрим на Json.NET documentation. В частности, справочная страница о классе JsonPropertyAttribute.

Цитирую:

«Инструктирует JsonSerializer всегда сериализовать элемент с указанным именем.»

Он объявлен в пространстве имен Newtonsoft.Json. Нам нужно определить, как это объявлено. Давайте посмотрим на исходный код Json.NET на CodePlex:

http://json.codeplex.com/

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

Угадайте, что отвечает на вопрос. Свойству атрибута AllowMultiple присвоено значение false. Таким образом, вы не можете украсить свойство, поле или параметр более одного раза этим атрибутом.

Даже если бы вы могли ожидать, что Json.net выяснит, какой атрибут использовать? Я бы создал типы для Twitter и Facebook отдельно, в которые вы можете десериализовать полученные данные JSON.

Итак:

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

Затем создать абстракции, которые ваше приложение использует вместо решения этих типов непосредственно. Они просто принадлежат к реализации определенных социальных сетей.

Twitter/Facebook/... speficic типы -> Ваши типы

Если вы сразу попытаться десериализации данных в ваших «общих типов», то вы просто собираетесь держать изо всех сил, потому что они не совпадают 100% с полученными данными, и вы столкнетесь с какой-то напуганной, труднодержащей логикой десериализации.

Другой вариант - создать собственный конвертер Json.NET.

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

Просто создать конвертер для Twitter и Facebook, и когда вы десериализации данные в формате JSON, просто указать, какой конвертер вы хотите использовать.

  • TwitterConverter
  • FacebookConverter

т.д .:

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

Во всяком случае я хотел бы попробовать, чтобы избежать загрязнения ваших типов классов с самой десериализации логикой.

+0

Ну, я надеялся, что это будет просто проверять один из них и использовать тот, который не является нулевым. Думаю, мне нужно придумать что-то еще ... Спасибо в любом случае! :) –

+0

Я думаю, что последний вариант должен работать довольно хорошо. – JefClaes

9

Я думаю, что я решил его в самый простой способ это возможно .....

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

    public string id { get; set; } 

Просто добавил и сделал один, установлен другой .. Он работает: P Иногда простые решения являются лучшими ?

+2

Будет работать, но виды загрязняют ваш тип со всеми свойствами. Половина из которых никогда не используется в зависимости от того, какой JSON вы десериализовали. –

+0

действительно, но он по крайней мере позволит мне проверить мою теорию, прежде чем делать это правильно :) –

+0

Bingo !!!!! для некоторых простых случаев это лучшее решение –

1

Если вы ищете универсальную модель класса для потребления, вы можете сделать это следующим образом.

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

Для Facebook,

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

Фот Twitter,

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

и вы можете забыть, что модель используется класс, а просто использовать GenericClass

Смежные вопросы