IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Sérialisation Json => Supprimer une propriété dynamiquement du contrat


Sujet :

C#

  1. #1
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 063
    Points : 420
    Points
    420
    Par défaut Sérialisation Json => Supprimer une propriété dynamiquement du contrat
    Bonjour à tous,

    J'ai un objet avec des propriétés de tous types dans ma classe tblOperation , notamment un appel vers une autre classe tblSource:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
        [DataContract]
        public class tblOperation {
            [DataMember]
            public tblSource source { get { return _source; } set { _source = value; } }
            ...
     
            public tblOperation Upd() {
                    var dcs = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(tblOperation), null, int.MaxValue, false, new MyOpeSurrogate(true), false); // En Json
                    System.IO.MemoryStream ms = new System.IO.MemoryStream();
                    dcs.WriteObject(ms, this); // Serialize l'objet
                    string postData = Encoding.UTF8.GetString(ms.ToArray());
                    ...
            }
        }
     
        [DataContract]
        public sealed class tblSource {
            private string _name;
            [DataMember]
            public int id { get; set; }
            [DataMember(Name = "name")]
            public string Name { get { return _name; } set { _name = value; } } // Nom
            [DataMember]
            public tblCreate create { get { return (id<1) ? new tblCreate(Name) : null; } private set { } }
            ...
        }
     
        [DataContract]
        public class tblCreate {
            [DataMember]
            public string name { get; set; }
            public tblCreate() { }
            public tblCreate(string pName) { name = pName; }
        }
     
        public class MyOpeSurrogate : IDataContractSurrogate {
     
            private bool toSerialise;
            /// <summary>Constructeur</summary>
            /// <param name="pToSerialise">Indique le sens qui sera utlisé (les API ne donnent pas le même format en GET qu'elles attendent en POST).</param>
            public MyOpeSurrogate(bool pToSerialise) { toSerialise = pToSerialise; }
     
            public Type GetDataContractType(Type type) { // var dcs = new DataContractJsonSerializer(typeof(tblContact), null, int.MaxValue, false, new MyGroupSurrogate(), false); // En Json
                    return type;
            }
     
            public object GetDeserializedObject(object obj, Type targetType) { // object newFamily = dcs.ReadObject(ms);
                    return obj;
            }
     
            public object GetObjectToSerialize(object obj, Type targetType) { // dcs.WriteObject(ms, this);
                    return obj;
            }
        }
    Tout fonctionne, mais j'ai besoin de mettre une condition:
    Si source.create est instancié , il ne faut pas mettre le champ source.name
    Bref, passer de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	"source": {
    		"id": 0,
    		"name": null
    	}
    à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	"source": {
    		"create": {
    			"name": "coucou"
    		}
    	}
    Comment faire ça ?
    Je suis dessus depuis un moment, j'ai vu des [OnSerializing()], mais je ne peux pas manipuler le contrat.
    J'ai cherché pour des attributs conditionnels, mais c'est prendre un marteau pilon pour écraser une mouche.
    J'ai regardé si on ne pouvait pas ôter dynamiquement le paramètre [DataMember], mais à première vue, on ne peux pas.
    J'ai cherché à intercepter les types string dans mon IDataContractSurrogate => GetObjectToSerialize, mais il n'intercepte que les types complexes à première vue.

    Quelqu'un a t-il une idée ?

    Cordialement.
    David.

  2. #2
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 195
    Points
    5 195
    Par défaut
    Bonjour

    si tu utilises la serialization via Newton json, cet article explique (option 3) comment le faire dynamiquement avec un ContractResolver

    http://www.tecsupra.com/serializing-...soft-json-net/
    The Monz, Toulouse
    Expertise dans la logistique et le développement pour
    plateforme .Net (Windows, Windows CE, Android)

  3. #3
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 063
    Points : 420
    Points
    420
    Par défaut
    Bonjour TheMonz,

    Merci.

    Dans mon projet, j'ai favorisé les bibliothèques du framework, plutôt que les externes.
    Je suis donc en DataContractJsonSerializer, pas en JsonConvert.
    Mais j'ai lu ton lien, ça a l'air de pouvoir répondre.
    Il faut approfondir car l'exemple n'est pas concret. Je basculerait si je suis vraiment bloqué.

    A coté, Au même moment, je viens de trouver une astuce: "EmitDefaultValue"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    [DataContract]
        public sealed class tblSource {
            private string _name;
            [DataMember(EmitDefaultValue = false)]
            public int id { get; set; }
            [DataMember(Name = "name", EmitDefaultValue = false)]
            public string Name { get { return _name; } set { _name = value; } }
            [DataMember] 
            public tblCreate create { get; set; }
            ...
    }
     
        [DataContract]
        public class tblOperation {
            [OnSerializing()]
            internal void OnSerializingMethod(StreamingContext context) { // OnSerializing OnSerialized OnDeserializing OnDeserialized
                if (this.source.id<1) {
                    this.source.create = new tblCreate(this.source.Name);
                    this.source.Name = null;
                }
            }
    }
    Ca m'ennuie de mettre du métier de "source" dans "operation", mais c'est simple et ça fonctionne.

    Sinon, J'ai une autre piste avec l'attribut "ScriptIgnore",
    Il faut que je voie ce qu'il y a derrière.

    Également avec ça: http://blogs.msdn.com/b/carlosfiguei...inspector.aspx
    Mais ça a l'air un peu lourd pour le besoin.
    David.

  4. #4
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 063
    Points : 420
    Points
    420
    Par défaut
    Ca, ça a l'air extra, mais ça ne fonctionne pas.
    https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            [DataMember(Name = "name")]
            public string Name { get { return _name; } set { _name = value; OnPropertyChanged(nameof(Name)); } } // Nom
            public void ResetName() { Name = null; }
            public void Resetname() { Name = null; }
            public bool ShouldSerializeName() { return (id > 0); }
            public bool ShouldSerializename() { return (id > 0); }
    Il ne passe jamais dedans.

    [EDIT]
    http://stackoverflow.com/questions/1...of-type-object
    Ca a l'air d'être fonctionnel que sur les controls.
    Ou le JsonConvert :-(
    David.

Discussions similaires

  1. Réponses: 4
    Dernier message: 20/07/2015, 20h44
  2. [JSON] Vérifier si une propriété existe
    Par Invité dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 01/12/2009, 13h37
  3. [héritage] supprimer une propriété
    Par Pol63 dans le forum VB.NET
    Réponses: 11
    Dernier message: 27/06/2007, 18h16
  4. Réponses: 3
    Dernier message: 25/12/2006, 00h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo