Jestem stosunkowo nowy w pracy z danymi C # i JSON i szukam wskazówek. Używam C # 3.0 z .NET3.5SP1 i JSON.NET 3.5r6.
Mam zdefiniowaną klasę C #, którą muszę wypełnić ze struktury JSON. Jednak nie każda struktura JSON dla wpisu, który jest pobierany z usługi sieci Web, zawiera wszystkie możliwe atrybuty zdefiniowane w klasie C #.
Robiłem coś, co wydaje się być niewłaściwe, trudne i po prostu wybierałem każdą wartość po kolei z JObject i przekształcałem ciąg znaków w żądaną właściwość klasy.
JsonSerializer serializer = new JsonSerializer();
var o = (JObject)serializer.Deserialize(myjsondata);
MyAccount.EmployeeID = (string)o["employeeid"][0];
Jaki jest najlepszy sposób deserializacji struktury JSON do klasy C # i obsługi ewentualnych brakujących danych ze źródła JSON?
Moja klasa jest zdefiniowana jako:
public class MyAccount
{
[JsonProperty(PropertyName = "username")]
public string UserID { get; set; }
[JsonProperty(PropertyName = "givenname")]
public string GivenName { get; set; }
[JsonProperty(PropertyName = "sn")]
public string Surname { get; set; }
[JsonProperty(PropertyName = "passwordexpired")]
public DateTime PasswordExpire { get; set; }
[JsonProperty(PropertyName = "primaryaffiliation")]
public string PrimaryAffiliation { get; set; }
[JsonProperty(PropertyName = "affiliation")]
public string[] Affiliation { get; set; }
[JsonProperty(PropertyName = "affiliationstatus")]
public string AffiliationStatus { get; set; }
[JsonProperty(PropertyName = "affiliationmodifytimestamp")]
public DateTime AffiliationLastModified { get; set; }
[JsonProperty(PropertyName = "employeeid")]
public string EmployeeID { get; set; }
[JsonProperty(PropertyName = "accountstatus")]
public string AccountStatus { get; set; }
[JsonProperty(PropertyName = "accountstatusexpiration")]
public DateTime AccountStatusExpiration { get; set; }
[JsonProperty(PropertyName = "accountstatusexpmaxdate")]
public DateTime AccountStatusExpirationMaxDate { get; set; }
[JsonProperty(PropertyName = "accountstatusmodifytimestamp")]
public DateTime AccountStatusModified { get; set; }
[JsonProperty(PropertyName = "accountstatusexpnotice")]
public string AccountStatusExpNotice { get; set; }
[JsonProperty(PropertyName = "accountstatusmodifiedby")]
public Dictionary<DateTime, string> AccountStatusModifiedBy { get; set; }
[JsonProperty(PropertyName = "entrycreatedate")]
public DateTime EntryCreatedate { get; set; }
[JsonProperty(PropertyName = "entrydeactivationdate")]
public DateTime EntryDeactivationDate { get; set; }
}
Przykładem JSON do przeanalizowania jest:
{
"givenname": [
"Robert"
],
"passwordexpired": "20091031041550Z",
"accountstatus": [
"active"
],
"accountstatusexpiration": [
"20100612000000Z"
],
"accountstatusexpmaxdate": [
"20110410000000Z"
],
"accountstatusmodifiedby": {
"20100214173242Z": "tdecker",
"20100304003242Z": "jsmith",
"20100324103242Z": "jsmith",
"20100325000005Z": "rjones",
"20100326210634Z": "jsmith",
"20100326211130Z": "jsmith"
},
"accountstatusmodifytimestamp": [
"20100312001213Z"
],
"affiliation": [
"Employee",
"Contractor",
"Staff"
],
"affiliationmodifytimestamp": [
"20100312001213Z"
],
"affiliationstatus": [
"detached"
],
"entrycreatedate": [
"20000922072747Z"
],
"username": [
"rjohnson"
],
"primaryaffiliation": [
"Staff"
],
"employeeid": [
"999777666"
],
"sn": [
"Johnson"
]
}
źródło
Czy próbowałeś użyć ogólnej metody DeserializeObject?
Wszelkie brakujące pola w danych JSON należy po prostu pozostawić NULL.
AKTUALIZACJA:
Jeśli ciąg JSON jest tablicą, spróbuj tego:
jarray
powinien byćList<MyAccount>
.KOLEJNA AKTUALIZACJA:
Wyjątek, który otrzymujesz, nie jest spójny z tablicą obiektów - myślę, że serializator ma problemy z twoją
accountstatusmodifiedby
właściwością typu Dictionary .Spróbuj wykluczyć
accountstatusmodifiedby
właściwość z serializacji i sprawdź, czy to pomaga. Jeśli tak, może być konieczne inne przedstawienie tej właściwości.Dokumentacja: serializacja i deserializacja JSON z Json.NET
źródło
DateTime AccountStatusExpiration
(na przykład) nie dopuszcza wartości null zgodnie z definicją w kodzie. Co trzeba by zrobić, żeby to unieważnić? Po prostu zmienićDateTime
naDateTime?
?dynamic
Aby ułatwić sobie pracę, możesz użyć typu C # . Technika ta sprawia również, że ponowne fakturowanie jest prostsze, ponieważ nie polega na magicznych łańcuchach.Json
Poniższy
json
ciąg jest prostą odpowiedzią na wywołanie http api i definiuje dwie właściwości:Id
iName
.DO#
Służy
JsonConvert.DeserializeObject<dynamic>()
do deserializacji tego ciągu do typu dynamicznego, a następnie po prostu uzyskuj dostęp do jego właściwości w zwykły sposób.Uwaga : łącze NuGet dla zestawu NewtonSoft to http://nuget.org/packages/newtonsoft.json . Nie zapomnij dodać:
using Newtonsoft.Json;
aby uzyskać dostęp do tych klas.źródło
DeserializeObject<dynamic>
z definicji nie jest sprawdzany pod kątem typu. Więc następujące wierszeresults.Id
iresults.Name
nie można ich zweryfikować w czasie kompilacji. Zamiast tego wszelkie błędy wystąpią w czasie wykonywania. Porównaj to z wywołaniem o silnym typie, takim jakDeserializeObject<List<MyAccount>>
. Odniesienia do tych właściwości można potwierdzić w czasie kompilacji. Użyciedynamic
, choć może być wygodne, wprowadza „magiczne ciągi” jako nazwy właściwości; zmniejszenie odporności IMHO.Możesz użyć:
tutaj:
json
to ciąg json,obj
to obiekt docelowy. Zobacz: przykładUwaga:
PopulateObject()
nie usunie dane użytkownika obj list, poPopulate()
,obj's
członek wola lista zawiera oryginalne dane i dane z json ciągźródło
Opierając się na odpowiedzi bbant, jest to moje kompletne rozwiązanie do deserializacji JSON ze zdalnego adresu URL.
Sposób użycia będzie następujący:
Gdzie
FeedResult
jest klasa wygenerowana przy użyciu generatora klas JSON firmy XamasoftOto zrzut ekranu ustawień, których użyłem, pozwalających na dziwne nazwy właściwości, których wersja internetowa nie mogła uwzględnić.
źródło
Okazało się, że mój obiekt został zbudowany nieprawidłowo. Użyłem http://json2csharp.com/ do wygenerowania mojej klasy obiektu z JSON. Gdy miałem właściwy obiekt, mogłem rzucać bez problemu. Norbit, błąd Nooba. Pomyślałem, że dodam to na wypadek, gdybyś miał ten sam problem.
źródło
Możesz spróbować sprawdzić niektóre generatory klas online, aby uzyskać dalsze informacje. Uważam jednak, że niektóre odpowiedzi były przydatne. Oto moje podejście, które może być przydatne.
Poniższy kod został stworzony z myślą o metodzie dynamicznej.
Ten kod zasadniczo umożliwia dostęp do elementów członkowskich zawartych w ciągu Json. Po prostu inny sposób bez konieczności zajęć.
query
,trend
iurl
są obiektami zawartymi w ciągu Json.Możesz także skorzystać z tej strony . Nie ufaj klasom w 100%, ale masz pomysł.
źródło
Zakładając, że Twoje przykładowe dane są poprawne, Twoje imię i nazwisko oraz inne wpisy w nawiasach to tablice w JS ... będziesz chciał użyć listy dla tych typów danych. i List for, powiedzmy accountstatusexpmaxdate ... Myślę, że przykład ma daty niepoprawnie sformatowane, tak niepewne, co jeszcze jest nieprawidłowe w twoim przykładzie.
To jest stary post, ale chciałem zwrócić uwagę na problemy.
źródło