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

Dotnet Discussion :

InvokeMember et setproperty [Débutant]


Sujet :

Dotnet

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 232
    Points : 93
    Points
    93
    Par défaut InvokeMember et setproperty
    Bonjour,

    Je découvre actuellement un peu le reflection et j'essaie en ce moment d'uiliser ces fonctions pour :
    1. créer une instance d'un objet
    2. modifier une propriété de cet objet


    J'ai réussi à faire la première étape mais je bloque sur la seconde car la propriété que je veux modifier n'est pas une propriété direct de l'objet mais plutôt la propriété d'une propriété de l'objet !
    Je conçois que tous ceci n'est pas très parlant. Voici donc un peu de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //creation d'une instance d'objet depuis son type
    Type typeClient = Assembly.GetExecutingAssembly().GetTypes().ToList().Where(t => t.Namespace == Namespace && t.Name == Name).First();
     
    object wsClient = typeClient.InvokeMember(null, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, null, null, null);
     
    //Modification d'une propriété
                        PropertyInfo property_ClientCredential = wsClient.GetType().GetProperty("ClientCredentials", BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty);
                        PropertyInfo UserNameObj = property_ClientCredential.PropertyType.GetProperty("UserName", BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty);
                        PropertyInfo UserName = UserNameObj.PropertyType.GetProperty("UserName", BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty);
                        UserName.SetValue(wsClient, User, null);
    Sans la réflexion je peux modifier cette fonction en direct comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    wsClient.ClientCredentials.UserName.UserName = User;
    Comme vous pourrez le constater j'arrive bien à accéder à la propriété via les getproperty seulement au moment du setValue j'ai l'erreur suivante :
    L'objet ne correspond pas au type cible.
    Si vous pouviez m'aider se serait super. Merci

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Le problème c'est ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UserName.SetValue(wsClient, User, null);
    UserName est une propriété de wsClient.ClientCredentials.UserName, pas de wsClient.

    Il faut récupérer la valeur de chaque objet intermédiaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    PropertyInfo credentialsProperty = wsClient.GetType().GetProperty("ClientCredentials");
    PropertyInfo userNameObjProperty = property_ClientCredential.PropertyType.GetProperty("UserName");
    PropertyInfo userNameProperty = UserNameObj.PropertyType.GetProperty("UserName");
     
    object credentials = credentialsProperty.GetValue(wsClient, null);
    object userNameObj = userNameObjProperty.GetValue(credentials, null);
    string userName = (string)userNameProperty.GetValue(userNameObj, null);
    J'ai un peu simplifié ton code au passage (il n'est pas nécessaire de préciser les BindingFlags pour des propriétés publiques) et j'ai remis à plat les noms de variables pour qu'on voit bien de quoi il s'agit...

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 232
    Points : 93
    Points
    93
    Par défaut
    Dans mon derniers essaie j'ai essayer de modifier directement la propriété "ClientCredential" seulement ceci c'est résolu par un échec et ceci est normal étant donnée que en direct d'un objet "wsClient" je n'ai pas accès aux méthodes "set" mais seulement au "get", par conséquent l'erreur suivante m'est retourné :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Méthode property-set introuvable.
    Car avec le code que tu m'a montré je comprend bien comment cela fonctionne pour récupérer les valeurs mais je ne comprends toujours pas comment faire pour modifier ma propriété.

    Merci pour l'aide

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 232
    Points : 93
    Points
    93
    Par défaut
    Pardon, c'est bon je viens d'avoir eu le dé clique!! hihi j'ai réussi en réutilisant ton code.

    Voici ce que cela donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    PropertyInfo credentialsProperty = wsClient.GetType().GetProperty("ClientCredentials");
    PropertyInfo userNameObjProperty = credentialsProperty.PropertyType.GetProperty("UserName");
    PropertyInfo userNameProperty = userNameObjProperty.PropertyType.GetProperty("UserName");
     
    object credentials = credentialsProperty.GetValue(wsClient, null);
    object userNameObj = userNameObjProperty.GetValue(credentials, null);
    userNameProperty.SetValue(userNameObj, User, null);
    Parfait et merci beaucoup

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Ah oui pardon, je t'ai montré un get alors que tu voulais faire un set... mais bon, tu t'en es sorti quand même

  6. #6
    Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Avril 2018
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2018
    Messages : 3
    Points : 4
    Points
    4
    Par défaut SetValue me retourne toujours la même erreur soit: L'objet ne correspond pas au type cible.
    Bonjour, j'ai vraiment besoin d'aide moi aussi avec cette erreur
    En gros je tente de faire un objet qui est un combobox sur le quel il y a un bouton pour éditer la données

    J'ai un DLL qui contient des forms qui eux contient des propriétés, de mon programme principale je veux charger cette dll pour afficher les données qui seront utilisé partout dans mon programme selon le type de données nécessaire mais le code me retourne un erreur comme L'objet ne correspond pas au type cible.

    Si quelqu'un peut m'aider SVP je ne m'en sort pas...
    Merci


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Microsoft.VisualBasic.CompilerServices.Symbols.Container.InvokeMethod(Method TargetProcedure, Object[] Arguments, Boolean[] CopyBack, BindingFlags Flags)
       à Microsoft.VisualBasic.CompilerServices.NewLateBinding.CallMethod(Container BaseReference, String MethodName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, BindingFlags InvocationFlags, Boolean ReportErrors, ResolutionFailure& Failure)
       à Microsoft.VisualBasic.CompilerServices.NewLateBinding.ObjectLateCall(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, Boolean IgnoreReturn)
       à Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateCall(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, Boolean IgnoreReturn)
       à Utility.modGlobal.SetValue(PropertyInfo info, Object inputObject, String propertyName, Object propertyVal) dans Utility\modGlobal.vb:ligne 177
    En gros j'ai une fonction qui appelle le DLL et je tourne a travers les données et j'envoi les données au DLL dans les propriétés

    Code VB.NET : 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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
     Private Function PropertyExists(ByVal objectt As Object, ByVal propertyy As String, value As Object) As Boolean
            Dim type As Type = objectt.GetType()
            Dim info As System.Reflection.PropertyInfo = type.GetProperty(propertyy)
            Dim reallyExists As Boolean = info IsNot Nothing
            If reallyExists Then
                SetValue(info, info, propertyy, value)
            End If
            Return reallyExists
        End Function
     
        Public Sub SetValue(ByVal info As System.Reflection.PropertyInfo,
                            ByVal inputObject As Object,
                            ByVal propertyName As String,
                            ByVal propertyVal As Object)
     
            'find the property type
            Dim propertyType As Type = inputObject.PropertyType
     
            'Convert.ChangeType does not handle conversion to nullable types
            'if the property type is nullable, we need to get the underlying type of the property
            Dim targetType As Type = If(IsNullableType(inputObject.PropertyType), Nullable.GetUnderlyingType(inputObject.PropertyType), inputObject.PropertyType)
            Try
                If (Not inputObject Is Nothing AndAlso inputObject.CanWrite) Then
                    inputObject.SetValue(info, Convert.ChangeType(propertyVal, targetType), Nothing) '<- ***  ici tombe en erreur  ****
                End If
     
            Catch ex As Exception
                modGlobal.MessageErreur("Erreur d'attribution valeur non valide", "Erreur d'attribution valeur " & propertyName, "Erreur dans" & info.Module.FullyQualifiedName & vbCrLf & "  non valide " & vbCrLf & ex.Message & vbCrLf & ex.StackTrace)
                Throw New NullReferenceException(ex.Message & vbCrLf & "Erreur d'attribution valeur " & propertyName & "  non valide ")
            End Try
        End Sub
     
        Private Function IsNullableType(ByVal type As Type) As Boolean
            Return type.IsGenericType AndAlso type.GetGenericTypeDefinition().Equals(GetType(Nullable(Of)))
        End Function
     
        Public Function StartObjectList(ByVal AssemblyName As String, ByVal ClassName As String, ByVal StartUpObject As Object) As Boolean
            Dim bRetour As Boolean = False
            Try
                Dim Chemin As String = IO.Path.Combine(IO.Path.GetDirectoryName(Application.ExecutablePath), AssemblyName & ".dll")
                If IO.File.Exists(Chemin) Then
                    Dim oAssembly As System.Reflection.Assembly = Reflection.Assembly.LoadFrom(Chemin)
                    Dim oType As System.Type = oAssembly.GetType(ClassName)
                    Dim oObject As System.Object
                    oObject = Activator.CreateInstance(oType)
                    oObject.Name = ClassName.Trim
     
                    If Not oObject Is Nothing Then
                        If TypeOf oObject Is List(Of String) Then
                            For Each s As String In oObject
     
                            Next
                        Else
                            If TypeOf StartUpObject Is DataTable Then
                                Dim tbl As DataTable = CType(StartUpObject, DataTable)
     
                                For Each row As DataRow In tbl.Rows
                                    For Each d As DataColumn In tbl.Columns
                                        If PropertyExists(oObject, d.ColumnName, row.Item(d.ColumnName)) Then
     
                                        End If
                                    Next
                                Next
                            End If
                        End If
                    End If
     
                    oObject.Icon = Nothing
     
     
                    oObject.ShowDialog()
                    bRetour = True
                Else
                    Using frm As New CustomMessageError("Erreur de chargement de DLL", "Fichier inexistant et objet non activé", "Le fichier manquant := " & Chemin)
                        frm.ShowDialog()
                    End Using
                End If
     
     
            Catch ex As Exception
                Using frm As New CustomMessageError("Erreur de chargement de DLL", ex.Message, ex.Message & vbCrLf & ex.StackTrace)
                    frm.ShowDialog()
                End Using
            End Try
            Return bRetour
        End Function

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

Discussions similaires

  1. [JBoss 5 et EJB 3 Webservices] setProperty must be overridden
    Par longbeach dans le forum Wildfly/JBoss
    Réponses: 2
    Dernier message: 12/09/2008, 12h20
  2. [setProperty] incompatible IE?
    Par speedev dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 14/03/2007, 16h14
  3. [Visual Web] Pb avec jsp:setProperty dans une page
    Par dfradet dans le forum NetBeans
    Réponses: 1
    Dernier message: 30/01/2007, 09h55
  4. générer dynamiquement l'attribut name dans <jsp:setProperty
    Par anthropo dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 29/08/2006, 17h49
  5. [C#] InvokeMember + const
    Par BoeufBrocoli dans le forum Windows Forms
    Réponses: 1
    Dernier message: 26/01/2006, 18h34

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