Sérialisation Json personnalisée de la classe

J’ai un code structuré comme ci-dessous.

public class Stats { public ssortingng URL { get; set; } public ssortingng Status { get; set; } public ssortingng Title { get; set; } public ssortingng Description { get; set; } public int Length { get; set; } } 

et

  public class UrlStats { public ssortingng URL { get; set; } public int TotalPagesFound { get; set; } public List TotalPages { get; set; } public int TotalTitleTags { get; set; } public List TotalTitles { get; set; } public int NoDuplicateTitleTags { get; set; } public List DuplicateTitles { get; set; } public int NoOverlengthTitleTags { get; set; } public List OverlengthTitles { get; set; } } 

Fondamentalement, je scanne un site Web à la recherche de statistiques telles que les balises de titre, les titres en double, etc.

J’utilise JQuery et passe des appels AJAX sur le Webservice et récupère les statistiques d’URL pendant que le processus est en cours pour afficher les statistiques d’URL utilisateur de loin, car il faut beaucoup de temps pour numériser un site Web volumineux. Donc, toutes les 5 secondes, je récupère les statistiques du serveur. À présent, le problème réside dans toutes les données variables de liste que je dois envoyer à la fin du traitement de l’parsing, et non lors des mises à jour. Que se passe-t-il actuellement, les données variables List sont également envoyées lors des mises à jour, ce qui représente un gros bloc de données et je souhaite envoyer uniquement les variables de type int requirejses pour afficher les mises à jour de processus.

En cherchant sur Internet, je n’ai rien trouvé d’utile à résoudre mon problème et j’ai trouvé que Json.NET est une très bonne bibliothèque mais je ne sais vraiment pas comment l’utiliser correctement pour obtenir ce que je veux.

En gros, je recherche des propriétés de sérialisation en fonction de leur type de données au moment de l’exécution, si c’est possible.

Il existe deux approches différentes pour votre problème.

Vous devez choisir le premier si vous envisagez de modifier vos classes plus souvent, car la première approche évite d’oublier de sérialiser une propriété nouvellement ajoutée. De plus, il est beaucoup plus réutilisable si vous souhaitez append une autre classe que vous souhaitez sérialiser de la même manière.

Si vous n’avez que ces deux classes et qu’il est fort probable qu’elles ne changeront pas, vous pouvez choisir la deuxième approche pour que votre solution rest simple.

1. Utilisez un convertisseur personnalisé pour sélectionner toutes les propriétés int .

La première approche consiste à utiliser un JsonConverter personnalisé qui sérialise une classe ou une structure en JsonConverter que les propriétés de type int . Le code pourrait ressembler à ceci:

 class IntPropertyConverter : JsonConverter { public override bool CanConvert(Type objectType) { // this converter can be applied to any type return true; } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // we currently support only writing of JSON throw new NotImplementedException(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value == null) { serializer.Serialize(writer, null); return; } // find all properties with type 'int' var properties = value.GetType().GetProperties().Where(p => p.PropertyType == typeof(int)); writer.WriteStartObject(); foreach (var property in properties) { // write property name writer.WritePropertyName(property.Name); // let the serializer serialize the value itself // (so this converter will work with any other type, not just int) serializer.Serialize(writer, property.GetValue(value, null)); } writer.WriteEndObject(); } } 

Ensuite, vous devez décorer votre classe avec un JsonConverterAtsortingbute :

 [JsonConverter(typeof(IntPropertyConverter))] public class UrlStats { // ... } 

Avertissement: Ce code n’a été testé que très grossièrement.


2. Choisissez les propriétés individuellement

La deuxième solution semble un peu plus simple: vous pouvez utiliser le JsonIgnoreAtsortingbute pour décorer les atsortingbuts que vous souhaitez exclure pour la sérialisation. Sinon, vous pouvez passer de “liste noire” à “liste blanche” en incluant explicitement les atsortingbuts que vous souhaitez sérialiser. Voici un exemple de code:

Liste noire: (j’ai réorganisé les propriétés pour un meilleur aperçu)

 [JsonObject(MemberSerialization.OptOut)] // this is default and can be omitted public class UrlStats { [JsonIgnore] public ssortingng URL { get; set; } [JsonIgnore] public List TotalPages { get; set; } [JsonIgnore] public List TotalTitles { get; set; } [JsonIgnore] public List DuplicateTitles { get; set; } [JsonIgnore] public List OverlengthTitles { get; set; } public int TotalPagesFound { get; set; } public int TotalTitleTags { get; set; } public int NoDuplicateTitleTags { get; set; } public int NoOverlengthTitleTags { get; set; } } 

Liste blanche: (également réorganisé)

 [JsonObject(MemberSerialization.OptIn)] // this is important! public class UrlStats { public ssortingng URL { get; set; } public List TotalPages { get; set; } public List TotalTitles { get; set; } public List DuplicateTitles { get; set; } public List OverlengthTitles { get; set; } [JsonProperty] public int TotalPagesFound { get; set; } [JsonProperty] public int TotalTitleTags { get; set; } [JsonProperty] public int NoDuplicateTitleTags { get; set; } [JsonProperty] public int NoOverlengthTitleTags { get; set; } } 

Oh compris, relisant votre question, je pense que vous pouvez sérialiser une projection de vos données.

Vous pouvez essayer ce qui suit:

 var json = JsonConvert.SerializeObject(new { u.TotalPagesFound, u.TotalTitleTags, u.NoDuplicateTitleTags, u.NoOverlengthTitleTags } ); 

Cela convertira en JSON uniquement les propriétés int de votre classe. C’est le moyen le plus simple et il est lié à la structure de votre classe. Si vous voulez quelque chose de plus général, vous devrez implémenter un convertisseur personnalisé.

Réponse originale:

Je ne vois aucun problème avec vos classes, vous n’avez rien de bizarre comme des références de boucles, donc Json.NET ne devrait pas avoir de problème pour sérialiser votre classe. Alors allez chercher Json.NET et vous pourrez alors essayer ce qui suit

 // create new instance of your url stat class var u = new UrlStats() { URL = "a.com", TotalPages = new List() { new Stats() { URL = "b.com", Status = "xxxx" } } }; // seralize! var json = JsonConvert.SerializeObject(u); Console.Write(json); 

Ce que je reçois avec cette méthode ressemble à ceci:

 {"URL":"a.com","TotalPagesFound":0,"TotalPages":[{"URL":"b.com","Status":"xxxx","Title":null,"Description":null,"Length":0}],"TotalTitleTags":0,"TotalTitles":null,"NoDuplicateTitleTags":0,"DuplicateTitles":null,"NoOverlengthTitleTags":0,"OverlengthTitles":null} 

Et cela me semble bien.