2011-09-20 13 views
15

Czytałem z DB długiego jsona. Chcę tylko jeden atrybut tego json.Czy mogę deserializować json do anonimowego typu w C#?

Mam dwie opcje: a. Stwórz interfejs dla tego jsona i przekształć go w deserializację. (Czy jest to przesada, ponieważ potrzebuję tylko jednego atrybutu?) b. Znajdź potrzebny podciąg (regex?)

który z nich jest preferowany?

zmiana: Używam .NET 3.5

Odpowiedz

26

Dlaczego nie deserializowania użyciu "LINQ do JSON" podejście JSON.NET „s (JObject etc) i po prostu poprosić o wartości trzeba po imieniu?

To wystarczająco dynamiczny, dzięki czemu nie trzeba utworzyć interfejs wszystko, ale jest to o wiele mniej kruche niż przy użyciu wyrażenia regularnego.

JObject json = JObject.Parse(text); 
JToken value = json["foo"]["bar"]; 

(wierzę Json.NET również, ale nie ma wsparcia na dynamic w .NET 4 nie szczególna potrzeba, aby go używać tutaj.)

2

Na .NET 4:

można zrobić coś rodzaj czegoś, co chcesz, minus potrzeba regex (i nie powinieneś używać wyrażenia regularnego do czegoś takiego!) za pomocą funkcji C# 4.0 opisanej tutaj: http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx

Jedynym minusem jest to, że nie możesz zagwarantować co e struktura xact obiektu.

ożywienia jest to, że zamiast dostępu członków poprzez yourDynamicObject['blah'], to tym bardziej kaczka-type-owski yourDynamicObject.blah

Na .NET 3.5:

Można użyć Json.NET: http://json.codeplex.com/

18

Regex musi być absolutnie poza wszelką dyskusją. Po prostu zapomnij o tym, to tak jakby nigdy nie istniało.

Tworzenie i praca z silnymi typami to dobra rzecz i pewnie tak jakbym poszła.

Ale jeśli chcesz, możesz też użyć dynamic:

class Program 
{ 
    static void Main() 
    { 
     var json = "{ 'foo': { 'bar': 'bar value', 'baz': [ 1, 2, 3 ] } }"; 
     var serializer = new JavaScriptSerializer(); 
     dynamic value = serializer.DeserializeObject(json); 
     Console.WriteLine(value["foo"]["baz"][1]); 
    } 
} 

drukuje 2 na konsoli.

+0

Używam C# 3.5 Nie sądzę, że istnieje typ dynamiczny. dobrze ? –

+2

@Elad Benda, nie, nie ma. Więc możesz użyć [Json.NET] (http://json.codeplex.com/), która oferuje podobną składnię. –

0

To zależy.

Opcja A jest bardziej surowa, zdyscyplinowana i formalna. Jednak znowu, jak powiedziałeś, może to być przesada. Jak gruby jest ten json? W perspektywie długoterminowej opcja A pozostawia w przyszłości potencjalną możliwość, że konieczne może być użycie więcej niż jednej nieruchomości.

Opcja B jest zdecydowanie bardziej nieformalna i prosta. To na pewno zadziała dzisiaj, ale może wymagać innego rozwiązania w przyszłości.

Może więc chcesz zawinąć cały proces w metodzie ukrywania implementacji przed wywołującym klientem. Zwróć obiekt niestandardowy z zapełnioną jedyną właściwością. Następnie, jeśli zajdzie taka potrzeba w przyszłości, możesz zmienić metodę, aby wykorzystać pełną deserializację nachylenia.

Uwaga: Nie sądzę, że możliwa jest deserializacja do anonimowego typu w języku C# 3.5.

1

Odnalezienie podciągu jest niebezpieczną optymalizacją.

Czy warto zoptymalizować proces (w porównaniu do deserializacji JSON) i bezpiecznie wykonać takie wyszukiwanie? Nie możemy odpowiedzieć na tak, ponieważ jest ona w większości zależna od kontekstu. Ale mam ochotę powiedzieć: NO, ponieważ oczywiste jest, że szukają problemów: Nawet jeśli teraz działa, może się zepsuć w przyszłości, gdy zmieni się struktura lub zawartość twojego obiektu.

1

Stary wątek, ale tutaj jest inna metoda na .NET 3.5: możesz rzucić obiekt zwrócony przez DeserializeObject na słownik < String, Object >. To trochę takie samo rozwiązanie jak dynamiczne słowo kluczowe .NET 4.0:

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
Object obj = serializer.DeserializeObject("{ 'name': 'vinicius fonseca', 'age': 31 }"); 
Dictionary<String, Object> ret = (Dictionary<String, Object>)obj; 
Console.WriteLine(ret["name"].GetType().Name); // Output: String 
Console.WriteLine(ret["name"].ToString()); // Output: vinicius fonseca 
Console.WriteLine(ret["age"].GetType().Name); // Output: Int32 
Console.WriteLine(ret["age"].ToString()); // Output: 31 

Mam nadzieję, że komuś pomaga.

Pozdrowienia

0

można zrobić:

var result = JsonConvert.DeserializeAnonymousType(json, new { Foo="", Bar=""}); 

ta zwróci obiekt dynamiczny z pól, które zdefiniowane.

+0

Czy mógłbyś jeszcze bardziej rozwinąć swoją odpowiedź, dodając nieco więcej opisu dostarczonego rozwiązania? – abarisone

Powiązane problemy