Je suis relativement nouveau dans le travail avec les données C # et JSON et je cherche des conseils. J'utilise C # 3.0, avec .NET3.5SP1 et JSON.NET 3.5r6.
J'ai une classe C # définie que je dois remplir à partir d'une structure JSON. Cependant, toutes les structures JSON d'une entrée extraite du service Web ne contiennent pas tous les attributs possibles définis dans la classe C #.
J'ai fait ce qui semble être de la mauvaise manière et difficile et j'ai simplement choisi chaque valeur une par une dans le JObject et transformé la chaîne en la propriété de classe souhaitée.
JsonSerializer serializer = new JsonSerializer();
var o = (JObject)serializer.Deserialize(myjsondata);
MyAccount.EmployeeID = (string)o["employeeid"][0];
Quelle est la meilleure façon de désérialiser une structure JSON dans la classe C # et de gérer les éventuelles données manquantes de la source JSON?
Ma classe est définie comme:
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; }
}
Et un exemple du JSON à analyser est:
{
"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"
]
}
la source
Avez-vous essayé d'utiliser la méthode générique DeserializeObject?
Tous les champs manquants dans les données JSON doivent simplement être laissés NULL.
METTRE À JOUR:
Si la chaîne JSON est un tableau, essayez ceci:
jarray
devrait alors être unList<MyAccount>
.UNE AUTRE MISE À JOUR:
L'exception que vous obtenez n'est pas cohérente avec un tableau d'objets - je pense que le sérialiseur a des problèmes avec votre
accountstatusmodifiedby
propriété de type Dictionary .Essayez d'exclure la
accountstatusmodifiedby
propriété de la sérialisation et voyez si cela aide. Si tel est le cas, vous devrez peut-être représenter cette propriété différemment.Documentation: sérialisation et désérialisation de JSON avec Json.NET
la source
DateTime AccountStatusExpiration
(par exemple) n'est pas nullable comme défini dans le code. Que faudrait-il pour le rendre annulable? Changer simplementDateTime
enDateTime?
?Vous pouvez utiliser le
dynamic
type C # pour faciliter les choses. Cette technique rend également la refactorisation plus simple car elle ne repose pas sur des chaînes magiques.Json
La
json
chaîne ci-dessous est une réponse simple à un appel api http et définit deux propriétés:Id
etName
.C #
Utilisez
JsonConvert.DeserializeObject<dynamic>()
pour désérialiser cette chaîne en un type dynamique, puis accédez simplement à ses propriétés de la manière habituelle.Remarque : Le lien NuGet pour l'assembly NewtonSoft est http://nuget.org/packages/newtonsoft.json . N'oubliez pas d'ajouter:
using Newtonsoft.Json;
pour accéder à ces classes.la source
DeserializeObject<dynamic>
n'est par définition pas "vérifié de type". Donc, les lignes suivantesresults.Id
etresults.Name
ne peuvent pas être vérifiées au moment de la compilation. Toutes les erreurs se produiront au moment de l'exécution. Comparez cela avec un appel fortement typé tel queDeserializeObject<List<MyAccount>>
. Les références à ces propriétés peuvent être confirmées au moment de la compilation. L'utilisation dedynamic
, bien que pratique, introduit des «chaînes magiques» comme noms de propriété; une réduction de la robustesse à mon humble avis.Vous pouvez utiliser:
ici:
json
est la chaîne json,obj
est l'objet cible. Voir: exempleRemarque:
PopulateObject()
n'effacera pas les données de la liste d'obj, aprèsPopulate()
, leobj's
membre de la liste contiendra ses données d'origine et les données de la chaîne jsonla source
S'appuyant sur la réponse de bbant, c'est ma solution complète pour désérialiser JSON à partir d'une URL distante.
L'utilisation serait comme:
Où
FeedResult
est la classe générée à l'aide du générateur de classes Xamasoft JSONVoici une capture d'écran des paramètres que j'ai utilisés, permettant des noms de propriétés étranges dont la version Web ne pouvait pas tenir compte.
la source
J'ai trouvé que j'avais mal construit mon objet. J'ai utilisé http://json2csharp.com/ pour me générer ma classe d'objets à partir du JSON. Une fois que j'ai eu le bon Oject, j'ai pu lancer sans problème. Norbit, erreur de Noob. Je pensais l'ajouter au cas où vous auriez le même problème.
la source
Vous pouvez essayer de vérifier certains des générateurs de classe en ligne pour plus d'informations. Cependant, je pense que certaines des réponses ont été utiles. Voici mon approche qui peut être utile.
Le code suivant a été créé avec une méthode dynamique à l'esprit.
Ce code vous permet essentiellement d'accéder aux membres contenus dans la chaîne Json. Juste une manière différente sans avoir besoin des classes.
query
,trend
Eturl
sont les objets contenus dans la chaîne JSON.Vous pouvez également utiliser ce site Web . Ne faites pas confiance aux classes à 100% mais vous voyez l'idée.
la source
En supposant que vos exemples de données sont corrects, que votre nom donné et les autres entrées entre crochets sont des tableaux dans JS ... vous voudrez utiliser List pour ces types de données. et Liste pour dire accountstatusexpmaxdate ... Je pense que votre exemple a les dates mal formatées, si incertain quant à ce qui est incorrect dans votre exemple.
Ceci est un ancien post, mais je voulais prendre note des problèmes.
la source