2013-02-28 1 views
1

Je trouve très difficile de poser cette question ici parce que je ne pense pas que je puisse offrir quoi que ce soit à cette communauté. Je programme actuellement une application qui, une fois lancée, demande à l'utilisateur de se connecter. Si les données saisies par l'utilisateur correspondent à celles de la base de données, l'utilisateur est connecté. L'application récupère ensuite les données relatives à l'utilisateur dans la base de données, telles qu'un ID utilisateur, un nom, un rôle.Get and setter dans VB.NET

Maintenant, je voudrais que cette information soit largement utilisée dans l'application. Ma situation actuelle:

  • Solution
    • Executable (projet principal)
    • Database.dll (classes etc)

Dans database.dll J'ai la classe suivante:

Public Class SessionProfile 
Public _gebruikersID As String 
Public _gebruikersNaam As String 
Public _gebruikersRole As String 

Public Property gebruikersID() As String 
    Get 
     Return _gebruikersID 
    End Get 

    Set(ByVal value As String) 
     _gebruikersID = value 
    End Set 
End Property 

Public Property gebruikersNaam() As String 
    Get 
     Return _gebruikersNaam 
    End Get 

    Set(ByVal value As String) 
     _gebruikersNaam = value 
    End Set 
End Property 

Public Property gebruikersRole() As String 
    Get 
     Return _gebruikersRole 
    End Get 

    Set(ByVal value As String) 
     _gebruikersRole = value 
    End Set 
End Property 
End Class 

Dans mon e principal xecutable Je me réfère à cette classe comme suit: Dim SessionProfile As New Database.SessionProfile() et dans mon formulaire de connexion J'utilise le code suivant pour définir le poseur:

If loginResult = 1 Then 
    SessionProfile.gebruikersID = SQLHook.Results("SELECT * FROM tblgebruikers WHERE GebruikersNaam = '" & TextGebruikersNaam.Text.Replace("'", "''") & "'", "GebruikersID") 
    SessionProfile.gebruikersNaam = SQLHook.Results("SELECT * FROM tblgebruikers WHERE GebruikersNaam = '" & TextGebruikersNaam.Text.Replace("'", "''") & "'", "gebruikersNaam") 
    SessionProfile.gebruikersRole = SQLHook.Results("SELECT * FROM tblgebruikers WHERE GebruikersNaam = '" & TextGebruikersNaam.Text.Replace("'", "''") & "'", "gebruikersRole") 
    DialogResult = DialogResult.OK 
Else 
    SessionProfile.gebruikersID = "" 
    SessionProfile.gebruikersNaam = "" 
    SessionProfile.gebruikersRole = "" 
    DialogResult = DialogResult.NO 
End If 

Maintenant, je reviens à ma principale forme et d'utiliser par exemple MsgBox(SessionProfile.GebruikersNaam) et je ne reçois rien retourné .

Y a-t-il une raison pour laquelle cette théorie ne fonctionne pas ou est-ce que quelque chose ne va pas? La requête est bonne parce que si vous les dimslez en tant que chaîne et msgbox eux, il affiche le texte correct.

Quelqu'un pourrait m'aider à résoudre mon problème?

+0

Vous avez déclaré une variable nommée 'SessionProfile' dans votre exécutable principal, pourriez-vous me dire si cette variable est passée au formulaire de connexion où vous définissez les propriétés ou avez-vous déclaré une nouvelle (et différente)? – Steve

+0

@Steve Dans l'exécutable principal j'ai deux formes nommées 'frmMain' et 'frmLogin' et dans les deux formes ce code est déclaré. –

Répondre

1

Si je comprends bien votre situation, vous êtes dans le scénario suivant.

Dans exécutable principal, quelque part, vous déclarez une variable (je changerai le nom d'expliquer mieux)

Dim currProfile As New Database.SessionProfile() 

cela signifie que vous avez créé une variable de type SessionProfile, maintenant que vous appelez le frmLogin

Dim form1 As new frmLogin() 
if DialogResult.OK = form1.ShowDialog() then 
    MsgBox(curProfile.GebruikersNaam) ' shows nothing' 

intérieur frmLogin vous avez déclaré une nouvelle (une autre) variables

Dim profile As New Database.SessionProfile() 

cette variable est différente et ne partage rien avec la variable déclarée dans le formulaire principal, définir ses propriétés ne signifie pas que l'autre variable SessionProfile voit ces changements.
Vous devez transmettre la première variable au frmLogin. Peut-être dans le constructeur.

Dim form1 As new frmLogin(currProfile) 
if DialogResult.OK = form1.ShowDialog() then 
    MsgBox(curProfile.GebruikersNaam) ' shows the name' 

et dans le constructeur frmLogin recevoir et stocker la variable passée dans

Dim profile As SessionProfile = Nothing 
Public Sub New(ByVal p As SessionProfile) 
    profile = p 
    InitializeComponent() 
End Sub 

Maintenant, lorsque vous définissez les propriétés de la variable de profil interne (frmLogin) vous définissez la propriétée de la même instance utilisé dans votre formulaire principal. Par ailleurs, évitez d'appeler vos variables avec le même nom que votre classe.Il est vraiment déroutant

+0

Je comprends votre code pour 80% et j'ai essayé de l'implémenter dans le mien et j'ai eu l'idée de 'résoudre le problème'. Maintenant, dans Public Sub New (ByVal p As SessionProfile) 'J'ai l'erreur suivante _In type généré par le concepteur 'frmLogin' devrait appeler la méthode InitializeComponent._ Je n'ai aucune idée de ce que cela signifie? Je suis vraiment désolé. –

+0

Eh bien, InitializeComponent est une méthode écrite pour vous par l'IDE de Visual Studio qui déclare et initialise chaque TextBox, Button, DataGrid, etc présents dans votre formulaire. Lorsque vous déclarez un nouveau constructeur explicite, vous devriez appeler cette méthode (j'ai oublié de l'écrire dans ma réponse). S'il vous plaît, lisez [cet article] (http://windowsdevcenter.com/pub/a/dotnet/2001/08/27/winforms.html) à propos de constructeur de formulaires, il est un peu long, mais couvre la base. – Steve

+0

Merci Steve. J'ai suivi les instructions et lu l'article que vous avez référé (c'est un peu long en effet mais j'en ai une petite idée). Maintenant, quand j'ai inséré tout votre code, j'obtiens l'erreur suivante dans 'frmLogin': ''profile' est déjà déclaré en tant que 'Private profile As Database.SessionProfile' dans cette classe. Je suis tellement désolé que je suis une énorme douleur dans le *** au sujet de mon code. –

1

Il ne semble pas y avoir de problème avec le code que vous avez posté ce qui expliquerait le problème que vous rencontrez, donc vous pourriez vouloir afficher le code sur votre formulaire principal et formulaire de connexion afin que nous peut jeter un coup d'oeil pour voir ce qui se passe.

Cependant, si vous avez le temps pour une révision rapide de code, je suggérerais que vos champs locaux soient privés pour la classe puisque vous les exposez via des propriétés publiques. Cela aidera à «protéger» les données sur le terrain de sources extérieures en modifiant les données sans accéder à vos setters.

donc ceci:

Public Class SessionProfile 
Public _gebruikersID As String 
Public _gebruikersNaam As String 
Public _gebruikersRole As String 

Public Property gebruikersID() As String 
    Get 
     Return _gebruikersID 
    End Get 

    Set(ByVal value As String) 
     _gebruikersID = value 
    End Set 
End Property ... 

devrait vraiment être ceci:

Public Class SessionProfile 
'Limit the scope to be private to the class; 
private _gebruikersID As String 
private _gebruikersNaam As String 
private _gebruikersRole As String 

Public Property gebruikersID() As String 
    Get 
     Return _gebruikersID 
    End Get 

    Set(ByVal value As String) 
     _gebruikersID = value 
    End Set 
End Property ... 

En second lieu, et peut-être plus important encore, vous devriez vraiment utiliser parameterized sql statements plutôt que la concaténation de chaîne d'un utilisateur de texte saisi. Je sais que vous travaillez avec une application installée, mais c'est néanmoins une bonne pratique. Aucune de ces suggestions ne vous aidera à répondre à votre question initiale, alors indiquez clairement plus de détails concernant le code sur les deux formulaires en question afin que nous puissions résoudre le problème.

+0

Je suis vraiment désolé. J'aurais dû fournir la question avec plus de code. Comme il s'agit d'énormes lignes de code, je les publie sur Pastebin. 'SessionProfile: http: // pastebin.com/07ZBVrWM' ' frmMain: http: // pastebin.com/qDkN9HbU' 'frmLogin: http: // pastebin.com/kRTkyRJF' –

+0

@Ruvvy pas de problème, il peut être difficile de savoir quel code cause le problème, donc choisir quel code publier peut être difficile;). Après avoir regardé votre code, je pense que vous trouverez la réponse de Steve très utile. –

+0

Merci. Je vais prendre un pic dans la réponse de Steve. –

0

Votre requête de base de données semble trop générale si elle ne peut renvoyer qu'une seule valeur à la fois. Il vous suffit de faire une requête pour obtenir toutes les données dont vous avez besoin:

Dim sp As SessionProfile = Nothing 

If loginResult = 1 Then 
    Dim sqlConnStr = "your sql connection string" 

    Dim nResults As Integer = 0 
    Using sqlConn = New SqlConnection(sqlConnStr) 

     ' N.B. always select only what you need, and always select explicitly 
     Dim sql = "SELECT GebruikersID, gebruikersNaam, gebruikersRole FROM tblgebruikers WHERE GebruikersNaam = @Naam" 

     Dim sqlCmd = New SqlCommand(sql, sqlConn) 
     sqlCmd.Parameters.AddWithValue("@Naam", TextGebruikersNaam.Text) 

     sqlConn.Open() 

     Dim rdr = sqlCmd.ExecuteReader 
     While rdr.Read 
      sp = New SessionProfile With {.gebruikersID = rdr.GetString(0), _ 
              .gebruikersNaam = rdr.GetString(1), _ 
              .gebruikersRole = rdr.GetString(2)} 

      nResults += 1 
     End While 

    End Using 

    If nResults <> 1 Then 
     Throw New Exception(String.Format("User {0} is in database more than once.", TextGebruikersNaam.Text)) 
    End If 

    If sp IsNot Nothing Then 
     ' sp now contains the session profile 
    End If 

End If 

En utilisant un paramètre SQL, vous éliminez la nécessité d'un traitement spécial de caractères tel apostrophe - remarquez comment ce code ne fait pas .Replacer ("'", "' '").

+0

Nous vous remercions de votre suggestion. Ma classe wrapper MySQL est un petit pas vers un bon. Si vous aimez vous pouvez recevoir une copie pour vérifier à quel point je développe une telle classe. –