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

VB.NET Discussion :

Problème Deserialize avec une valeur vide dans le xml


Sujet :

VB.NET

  1. #1
    Membre Expert Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Par défaut Problème Deserialize avec une valeur vide dans le xml
    Holla,

    Je dois deserialiser un petit fichier xml.
    Pour se faire, j'ai créer dans mon programme une classe serialisable avec plein de propriétés typées (string, int, decimal, datetime etc...).

    Mon problème: Quand les propriétés ne sont pas des strings (genre integer), et que dans le fichier XML la valeur est vide, il refuse la deserialisation.

    J'ai tenté de changer le type de la propriété en Nullable (of Integer) et de tester if valeur.HasValue

    Après dans le set, je voulais mettre valeur en type string, et de la convertir en integer... mais évidemment il ne veut pas que le type de la valeur du set soit différent de la propriété en elle même.

    Mais rien n'y fais, il faut une valeur.

    Je pourrai passer toutes mes propriétés en String et faire les conversion après, mais j'aime pas trop.
    Je en trouve pas la solution sur google évidemment... Trop de sujets qui n'ont rien à voir.

    Si quelqu'un a une astuce, je suis preneur.

  2. #2
    Inactif  

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2012
    Messages
    4 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 4 903
    Billets dans le blog
    36
    Par défaut
    Bonjour,

    Vite fait et sans tester. Donc, cela peut être des âneries et je l'assume.

    1 - Ce n'est (probablement) pas l'idéal, mais tu peux essayer d'intercepter l'exception et mettre une valeur genre "N/D"

    2 - Ce n'est pas complètement sans risque, mais, tu travailles en amont, en mettant une "valeur improbable", genre 1 X 1030, "N/D" etc., au moment de la sérialisation. Et tu lui offre un traitement particulier au moment de la désérialisation. C'est le genre d'artifice qui sert parfois dans certains algorithmes de calcul d'optimisation; pour mettre absolument un nombre et être à peu près sur que l'on pourra quand même l'empêcher de nuire. ( Ex : Un nombre "immense" pour minimiser, un nombre "minuscule" pour maximiser.)

  3. #3
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Par défaut
    Hello,
    Citation Envoyé par mactwist69 Voir le message
    Mon problème: Quand les propriétés ne sont pas des strings (genre integer), et que dans le fichier XML la valeur est vide, il refuse la deserialisation.

    J'ai tenté de changer le type de la propriété en Nullable (of Integer) et de tester if valeur.HasValue

    Après dans le set, je voulais mettre valeur en type string, et de la convertir en integer... mais évidemment il ne veut pas que le type de la valeur du set soit différent de la propriété en elle même.

    Je pourrai passer toutes mes propriétés en String et faire les conversion après, mais j'aime pas trop.
    ...
    Si quelqu'un a une astuce, je suis preneur.
    Il existe bien une astuce, mais pas sur qu'elle te convienne.
    Il faut masquer la propriété pour la sérialisation, puis créer une propriété spécifique pour la sérialisation de type string qui se sert de la propriété masquée et fait la conversion. (Difficile à suivre hein, donc un petit exemple pour ettayer)
    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
        <XmlElement("NbReserv")>
        Public Property NbReservFormatted As String
            Get
                Return NbReserv.ToString
            End Get
            Set(value As String)
                Integer.TryParse(value, NbReserv)
            End Set
        End Property
        Private _NbReserv As Integer
        <XmlIgnore()>
        Public Property NbReserv() As Integer
            Get
                NbReserv = _NbReserv
            End Get
            Set(ByVal value As Integer)
                _NbReserv = value
            End Set
        End Property
    Attention, si la propriété n'est pas renseignée, par défaut il colle un 0 (zéro) (tester le tryparse si tu veux faire quelque chose)

    Je nomme cette propriété spécifique afin qu'elle est le même nom que la propriété réelle, ainsi cela est transparent dans le fichier xml.

    Reste à voir comment rendre NbReservFormatted non visible pour le dev (intellisense, ...)
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  4. #4
    Membre Expert Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Par défaut Bonjour
    Merci pour vos réponses.

    Pour la première, j'avais déjà essayer de protéger le code des assesseurs, mais ça ne fonctionnait pas.

    Pour la deuxième, pas bête l'idée. Et il est vrai que pour bien faire les choses, il faudrait rendre la propriété Formated invisible pour le dev.
    Je vais essayer je vous tiens au jus.

  5. #5
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Par défaut
    En utilisant les attributs (je viens d'y penser)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        <EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> _
        <XmlElement("NbReserv")> _
        Public Property NbReservFormatted As String
            Get
                Return NbReserv.ToString
            End Get
            Set(value As String)
                Integer.TryParse(value, NbReserv)
                'If Not Integer.TryParse(value, NbReserv) Then NbReserv = Integer.MinValue ' si l'on ne teste pas : 0 par défaut pour les valeurs non présentes
            End Set
        End Property
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  6. #6
    Membre Expert Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Par défaut Alors
    Bon et bien j'ai enfin pu me repecher sur mon problème.
    La méthode est parfaite pour moi car propre et le travail effectué est invisible pour l'utilisateur de l'ojet, je mets donc la code final :

    (Au passage j'avais une contrainte de plus, ma variable de classe est Nullable) :


    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
     
       Private Temperature as Decimal? = Nothing
     
      <EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> _
      <XmlElement(OilTemperatureXmlName)> _
                Public WriteOnly Property TemperatureFormatted() As String
                    Set(ByVal value As String)
                        Dim ValTemp As Decimal = 0
                        If Decimal.TryParse(value, ValTemp) Then
                            Me.Temperature = ValTemp
                        Else
                            Me.Temperature = Nothing
                        End If
                    End Set
                End Property
     
                <XmlIgnore()> _
                Public Property Temperature() As Decimal?
                    Get
                        Return Me.Temperature
                    End Get
                    Set(ByVal value As Decimal?)
                        Me.Temperature = value
                    End Set
                End Property

    Du coup :
    - la propriété TemperatureFormatted n'est utilisée que pour la desérialisation et rempli ma variable de classe privée en faisant les tests.
    - Je mis cette même propriété en WriteOnly parce que je ne sérialise pas cette classe.

    - Côté code, la propriété Temperature est du bon type et fonctionne normalement
    - Et en enlevant la propriété TemperatureFormatted de l'intellisense, tout ce petit business est donc invisible.

    Merci bien rv26t

  7. #7
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Par défaut
    De rien
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  8. #8
    Membre Expert Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Par défaut
    Aïe !! Obliger de revenir sur mon code puisque je me suis rendu compte (bien tard) d'une erreur.

    Si les propriétés qui récupèrent les valeurs du fichier XML sont en WriteOnly, alors ces propriétés sont tout bonnement ignorées
    Donc même si je n'ai pas besoin du Get, il le faut. Pas le temps de creuser le pourquoi, mais bon, le code final qui marche est celui-ci :

    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
      Private Temperature as Decimal? = Nothing
     
      <EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> _
      <XmlElement(TemperatureXmlName)> _
                Public Property TemperatureFormatted() As String
                    Get
                         Return Me.Temperature.ToString
                    End Get                
                    Set(ByVal value As String)
                        Dim ValTemp As Decimal = 0
                        If Decimal.TryParse(value, ValTemp) Then
                            Me.Temperature = ValTemp
                        Else
                            Me.Temperature = Nothing
                        End If
                    End Set
                End Property
     
                <XmlIgnore()> _
                Public Property Temperature() As Decimal?
                    Get
                        Return Me.Temperature
                    End Get
                    Set(ByVal value As Decimal?)
                        Me.Temperature = value
                    End Set
                End Property

  9. #9
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Par défaut
    Si mes souvenir sont bon, on ne peut pas serialiser les propriétés private, protected, readonly, writeonly, ou nulle (problème du début).
    Mais pour toi, cela n'est pas génant tel que c'est (avec Get et set) puisque la propriété est cachée.

    [Edit]
    Afin d'éviter une confusion, une chaîne de caractère nulle nothing est différente d'une chaîne vide "".
    Donc ici, s'il n'y a pas de valeur, la sérialisation donne une chaîne vide pour le type string.
    Par contre pour les autres types integer, double, ... cela est considéré comme une valeur nulle donc pas sérialisable.
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  10. #10
    Membre Expert Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Par défaut
    on ne peut pas serialiser les propriétés private, protected, readonly, writeonly, ou nulle (problème du début). Mais pour toi, cela n'est pas génant tel que c'est (avec Get et set) puisque la propriété est cachée.
    -> Exact, mais c'était plus vicieux pour le WriteOnly, puisque les propriétés étaient tout simplement ignorées, contrairement aux valeurs nuls qui déclenchaient une exception.

    Par contre pour les autres types integer, double, ... cela est considéré comme une valeur nulle donc pas sérialisable.
    -> J'avais espéré que comme on peut déclarer dans VB.NET des types comme Integer à Nullable, cela puisse être possible.
    Mais bon, c'est pas très grave avec ce contournement.


    Bon je crois que cette fois, le ticket est clos. En espérant que ça aide d'autres personnes.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Enregistrer une valeur vide dans un champ DATE
    Par delilou dans le forum Développement de jobs
    Réponses: 3
    Dernier message: 25/01/2012, 15h54
  2. [JNDI] Problème pour insérer une valeur vide
    Par felix79 dans le forum API standards et tierces
    Réponses: 0
    Dernier message: 20/10/2011, 11h37
  3. [EJBQL] Requête avec une valeur constante dans les champs résultat
    Par adamo901 dans le forum Java EE
    Réponses: 1
    Dernier message: 13/04/2009, 00h32
  4. [resolut]Insertion d'une valeur vide dans un champ mémo
    Par bak47 dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 23/04/2008, 19h24
  5. Avoir une valeur vide dans un DropDownList
    Par matinho dans le forum C#
    Réponses: 19
    Dernier message: 12/11/2007, 15h37

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