Entwickler-Ecke

Datenbanken (inkl. ADO.NET) - Benutzer und Password in Datenbankdatei Reihe vergleichen


mkRE - Mi 09.12.15 22:21
Titel: Benutzer und Password in Datenbankdatei Reihe vergleichen
Hallo zusammen ich habe gestern ein altes Testprojekt von mir geöffnet um ein altes Problem zu behandeln bei dem ich stehen geblieben bin.
Es handelt sich um eine Datenbank Anwendung erstellt mit C# Visual Studio 2012 bei der ich auf eine Datenbank Datei "Data.mdf" zugreife bzw. Passwörter und Benutzernamen verwalten möchte.
Mein Problem bei der Anwendung ist, dass ich nicht weiß wie ich in einer Reihe der der Datenbank den Benutzernamen und Passwort entsprechend der Eingabe in einer TextBox vergleichen kann.

Ich suche nach einer Möglichkeit die jeweiligen texte in einer Reihe in der Datenbankdatei zu vergleichen und dann entsprechend zu reagieren.
Natürlich möchte ich hierbei die ganze Datenbankdetei durchsuchen ob einer der Reihen den Eingaben entspricht.

Könnt ihr mir hierbei weiterhelfen?

Folgender Code wird momentan verwendet:

C#-Quelltext
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:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Data.SqlClient;

namespace BTG_Database
{
    public partial class frmAnmeldung : Form
    {
        public frmAnmeldung()
        {
            InitializeComponent();
        }

        private void btnAnmelden_Click(object sender, EventArgs e)
        {
            try
            {
                SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Data.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True;");
                SqlDataAdapter sda = new SqlDataAdapter("Select Count(*) From Login where Username='" + txtUsername.Text + "' and Password = '" + txtPasswort.Text + "'", con);

                DataTable dt = new DataTable();
                sda.Fill(dt);

                if (dt.Rows.Count == 1 && dt.Rows[0][0].ToString() == "1")
                {
                    frmBTGDatabase.label_1.Text = "Angemeldet";
                    frmBTGDatabase.button_1.Enabled = true;
                    frmBTGDatabase.button_2.Enabled = true;
                    frmBTGDatabase.button_3.Enabled = true;
                    frmBTGDatabase.button_4.Enabled = true;
                    frmBTGDatabase.button_5.Enabled = true;
                    frmBTGDatabase.button_6.Enabled = true;
                    this.Close();
                }
                else
                {
                    if (dt.Rows.Count == 2 && dt.Rows[1][1].ToString() == "1")
                //  if (txtUsername.Text == "Admin" && txtPasswort.Text == "111111")
                    {
                    frmBTGDatabase.label_1.Text = "Angemeldet";
                    frmBTGDatabase.button_1.Enabled = true;
                    frmBTGDatabase.button_2.Enabled = true;
                    frmBTGDatabase.button_3.Enabled = true;
                    frmBTGDatabase.button_4.Enabled = true;
                    frmBTGDatabase.button_5.Enabled = true;
                    this.Close();

                    }
                    else
                    {
                        MessageBox.Show("Benutzername oder Passwort falsch!");
                    }
                }
                       
            }
            catch
            {
                MessageBox.Show("Probleme bei der Datenbankanbindung Data.mdf ");
            }
        }

        private void frmAnmeldung_Load(object sender, EventArgs e)
        {
            this.ActiveControl = txtUsername;
            frmBTGDatabase.toolstripmenuitem_1.Enabled = false;
        }

        private void frmAnmeldung_Closed(object sender, FormClosedEventArgs e)
        {
            frmBTGDatabase.toolstripmenuitem_1.Enabled = true;
        }

        private void btnSchließen_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}



Vielen Dank

Gruß mkRE


Yankyy02 - Mi 09.12.15 22:56

Hallo mkRE,

deine herangehensweise würde ich nochmal überdenken. Besser wäre es dir eine eigene Methode zuschreiben die 2 String Werte (Passwort,Username) entgegennimt und einen bool Wert zurückliefert wenn das Passwort und der User vorhanden sind und zusammen passen. Anhand dieses Rückgabewertes kannst du dann deine Oberfläche "freischalten". In dieser Methode würde ich mit SQL Parametern arbeiten und mit einem SQLDataReader. Wenn du bei Google folgenden Suchbegriff verwendest --> User Login C# SQL <-- erhältst du unzählige Beispiele wie man soetwas lösen kann.

LG


mkRE - Do 10.12.15 00:55

Hallo Yankyy02

super und danke für deinen Tipp!!!

Hab da was zum anschauen und lesen gefunden und zum testen folgendes ausprobiert was sofort funktionierte:


C#-Quelltext
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:
        private void btnAnmelden_Click(object sender, EventArgs e)
        {
            try
            {
                SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Data.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True;");
                SqlCommand cmd = new SqlCommand("Select * From Login where Username='" + txtUsername.Text + "' and Password = '" + txtPasswort.Text + "'", con);
                con.Open();

                SqlDataReader re = cmd.ExecuteReader();

                if (re.Read())
                {
                    frmBTGDatabase.label_1.Text = "Angemeldet";
                    frmBTGDatabase.button_1.Enabled = true;
                    frmBTGDatabase.button_2.Enabled = true;
                    frmBTGDatabase.button_3.Enabled = true;
                    frmBTGDatabase.button_4.Enabled = true;
                    frmBTGDatabase.button_5.Enabled = true;
                    frmBTGDatabase.button_6.Enabled = true;
                    this.Close();
                }
                else
                {
                    MessageBox.Show("Benutzername oder Passwort falsch!");
                    this.Close();                                      
                }
                       
            }
            catch
            {
                MessageBox.Show("Probleme bei der Datenbankanbindung Data.mdf ");
            }
        }


Das ist halt nur zum Funktionstest. Ich nehme deinen Tip mit der Methode noch mit und so ansetzen.
Hätte nicht gedacht das es so easy geht man und ich hab mich mit dem Count dum und dämlich versucht :-)


Yankyy02 - Do 10.12.15 01:04

Der Code mag zwar "funktionieren" bzw. compilieren aber Sinn macht er keinen! Wenn du das so ausführst wirst du immer angemeldet werden! Hier findet keine Prüfung statt ob der Benutzername vorhanden ist bzw. das Passwort übereinstimmt! Überleg mal was du mit if(re.Read()) prüfst!

LG


mkRE - Do 10.12.15 14:14

Hallo Yankyy02,

Danke für deine Antwort ich habe gedacht das es so easy ist :-(.

Da ich vemutet habe das re.Read() jede reihe auf den String in der jeweiligen TextBox auf Gleichheit prüft das es so ok ist. Funktionierte ja auch habe in der Anwendungs Datenbank zwei User eingefügt und kann mich entsprechend der Daten anmelden. Gebe ich etwas anderes bekomme ich die info das Benutzerdaten falsch sind.


Was meinst du genau mit "wirst du immer angemeldet werden"?
Meinst du mit der Datenbak verbunden zu sein oder das ich in der Applikation angemeldet bleibe?In Der Applikation habe ich auch daran gedacht sich abzumelden.

Ich gehe das ganze heute Abend noch mal durch und schaue was das re.Read() genau prüft.

Vielleicht kannst du mir noch einige Hinweise geben bitte.

Danke.

Viele Grüße


Yankyy02 - Do 10.12.15 17:19

Hey mkRE,

die Read() Methode des SQLDataReaders prüft ob noch weitere Daten vorhanden sind und gibt dann jeweils true oder false zurück. Hierbei wird nicht überprüft ob der Username zum Passwort passt oder ähnliches. Da du im Select Statement bereits Username und Passwort angibst liefert er natürlich false zurück wenn der Username samt Passwort nicht vorhanden ist. Dir sollte nur klar sein was die Read Methode genau tut und für was sie dar ist.

LG


mkRE - Do 10.12.15 20:23

Hallo Yankyy02,

im allgemeinen so wie ich dich verstehe war dein Ziel zu verstehen wie die Read() Methode funktioniert ist das richtig?
So wie du beschrieben hast wie die Methode Read() arbeitet steht auch in den Beschreibungen von Windows beschrieben.
Aber die Lösung ganz gesehen ausreichend?!

Bitte verstehe das ich ein Anfänger im Bezug auf Datenbank Anwendungen bin :-) und möchte gerne dazulernen wie es tatsächlich gemacht wird.

Deinen weiteren Tipp mit der eigens für die Passwort und Username Kontrolle wie unten von dir beschrieben werde ich auch machen ich ändere das Konzept!:-)

Viele Grüße

mkRE


Yankyy02 - Do 10.12.15 21:26

Hallo mkRE,

grundsätzlich ist es mir um das gegangen. :wink: Gerade als Anfänger so wie du dich beschreibst hat man meist das Ziel so schnell wie möglich ein Ergebnis zu erzielen. Ich bin selbst kein Profi bzw. Professioneller Entwickler und wenn ich so manchen Code meiner Anwendungen posten würde bin ich mir sicher das 10 weitere sofort die Hände über den Kopf zusammenschlagen würden. :D Wenn es dir für das erste reicht kannst du es natürlich so lassen aber ich würde dir raten das doch nochmal zu überdenken! Einen Tipp hab ich noch für dich und das war auch mein großer Fehler den ich begangen habe ....
schau dir wenn du Methoden aus der .Net Bibliothek verwendest die Doku dazu an. Meist fällt dann der Groschen wie man so schön sagt von selbst.

PS: Copy & Paste hilft dir zwar im ersten Moment weiter aber wenn du das nächste mal wieder auf solch ein Problem stoßt fängst du wieder von vorne an.

LG


mkRE - Do 10.12.15 21:55

Hallo Yankyy02,

dafür das du kein Professioneller bist finde ich super wie du Helfen kannst!!
Du hasst aber recht man sollte nicht nur dem Ergebnis nachstreben ohne den Hintergrund zu verstehen.
Daher möchte ich im ernst den Problemen so entgegen gehen die Lösungen zu verstehen und freue mich das man von einigen auch gefordert wird.
Manchmal dauert es länger die Tipps zu verarbeiten :-).
Bei der Anwendung die ich wieder aufgegriffen habe womit du mir hilft sind einige Fehler und offene Punkte
die ich gerne abarbeiten möchte um das abzuschließen. Das nächste Projekt was ich Plane hat mit Zeichnen und Datenbank zu tun.
Alle bisherigen Fehler bzw. falschen Herangehensweisen will ich dort dann entsprechend weglassen.

Zu der Datenbankdatei habe ich noch folgendes Problem und zwar musste ich diese Datei die mit MSQL 2012 erstellt wurde aktualisieren auf MSQL 2014.
Nun kann ich auf die Datei zugreifen und die dort eingetragenen Benutzerdaten auch lesen. Nun seit gestern öffne ich die Tabelle wie gehabt, jedoch zeigen sich dort die Daten nicht.
Keine Ahnung warum, als würde ich eine ganz andere Datenbankdatei öffnen. Ich sende gleich mal den Code der jedoch in Ordnung sein sollte.

Viele Grüße


mkRE - Do 10.12.15 22:23


C#-Quelltext
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:
namespace BTG_Database
{
    public partial class frmBenutzerkonto : Form
    {
        private string message = "Möchten Sie wirklich das Fenster BTG-Benutzerkonto verlassen?";
        private string caption = "Fenster verlassen";

        public frmBenutzerkonto()
        {
            InitializeComponent();
        }

        private void lOGINBindingNavigatorSaveItem_Click(object sender, EventArgs e)
        {
            this.Validate();
            this.lOGINBindingSource.EndEdit();
            this.tableAdapterManager.UpdateAll(this.dataDataSet1);

        }

        private void frmBenutzerkonto_Load(object sender, EventArgs e)
        {
            this.lOGINTableAdapter.Fill(this.dataDataSet1.LOGIN);
            this.lOGINTableAdapter.Fill(this.dataDataSet1.LOGIN);
            frmBTGDatabase.button_6.Enabled = false;

        }

        private void lOGINDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            this.Close(); 
        }

        private void frmBenutzerkonto_Closed(object sender, FormClosedEventArgs e)
        {
            frmBTGDatabase.button_6.Enabled = true;
        }

        private void frmBenutzerkonto_Closing(object sender, FormClosingEventArgs e)
        {
            DialogResult result = MessageBox.Show(message, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (result == DialogResult.No)
            {
                e.Cancel = true;
            }
        }
    }
}


Und hier soll ja eigentlich die Tabelle gefüllt werden:


C#-Quelltext
1:
2:
3:
4:
5:
6:
        private void frmBenutzerkonto_Load(object sender, EventArgs e)
        {
            this.lOGINTableAdapter.Fill(this.dataDataSet1.LOGIN);
            this.lOGINTableAdapter.Fill(this.dataDataSet1.LOGIN);
            frmBTGDatabase.button_6.Enabled = false;
        }


Eigentlich ist der Code nicht aussagekräftig aber ich kann mir nicht weiterhelfen warum das nicht angezeigt wird.
Vorher ging das :-(

Viele Grüße


Ralf Jansen - Do 10.12.15 22:30

Warum füllst du die DataTable denn gleich 2mal?
Hängt die lOGINBindingSource denn noch an deinem lOGINDataGridView?

Du hast denn Code debuggt und geschaut das nach dem lOGINTableAdapter.Fill auch Daten in der dataDataSet1.LOGIN DataTable drin stecken? Dann weißt du zumindest ob Daten aus der Datenbank kommen oder ob etwas beim Binding zwischen DataSet und DataGridView schief gelaufen ist.


mkRE - Fr 11.12.15 00:53

Hallo Ralf

Das doppelt befüllen ist ein versehen von mir habs nicht gelöscht war aber standardmäßig nicht im Code.

Die lOGINBindingSource hängt an dem lOGINDataGridView habe das kontrolliert.

Getestet habe ich im normalen Ablauf wie im Code, Benutzerkonto Form hat sich geladen und ich hätte erwartet das die Tabelle mit den voreingestellten Daten befüllt wird.

Ich finde einfach den Fehler nicht :-(


Th69 - Fr 11.12.15 09:54

Hallo mkRE,

auch für dich der Tipp, lerne mit dem Debugger umzugehen. Wenn du nicht weißt, was der alles kann: [Artikel] Debugger: Wie verwende ich den von Visual Studio? [http://www.mycsharp.de/wbb2/thread.php?threadid=109261]

Du hast die Frage von Ralf aber noch nicht beantwortet:
Ralf Jansen hat folgendes geschrieben:
Du hast denn Code debuggt und geschaut das nach dem lOGINTableAdapter.Fill auch Daten in der dataDataSet1.LOGIN DataTable drin stecken? ...


mkRE - Sa 12.12.15 13:32

Hallo TH69,

danke für den Debugger Link im allgemeinen habe ich öfters mit dem Debugger gearbeitet Breakpoints setzen usw. hat mir auch oft weiter geholfen auch bei anderen Entwicklungs Software.
Jedoch lese ich mir den Link durch mit Sicherheit ist das eine oder andere beschrieben was ich nicht kannte beim Visual Studio.

Auf die Frage von Ralf muss ich gestehen das ich nicht geschaut habe ob nach dem lOGINTableAdapter.Fill auch Daten in der dataDataSet1.LOGIN DataTable drin stecken mittels Debugger.

Ich melde mich sobald ich das getan habe ggf. erkennt man dort etwas.

Vielen Dank

Gruß

mkRE


mkRE - So 13.12.15 00:02

Hallo zusammen habe gerade einmal einen Haltepunkt beim lOGINTableAdapter.Fill angefügt und nach dem Laden der Benutzerseite einige Ausnahme gesehen mit folgenden Hinweisen siehe auch Bild im Anhang:
Zitat:
Ausnahme:Ausgelöst: "Cannot open database "C:\USERS\USER\DOCUMENTS\BTG-DATABASE_20_08_2013\BTG-DATABASE\BTG-DATABASE\BIN\DEBUG\DATA.MDF" requested by the login. The login failed.
Login failed for user 'xxx\User'." (System.Data.SqlClient.SqlException)
System.Data.SqlClient.SqlException wurde ausgelöst: "Cannot open database "C:\USERS\USER\DOCUMENTS\BTG-DATABASE_20_08_2013\BTG-DATABASE\BTG-DATABASE\BIN\DEBUG\DATA.MDF" requested by the login. The login failed.
Login failed for user 'xxx\User'."
Time: 12.12.2015 22:32:29
Thread:Hauptthread[4360]

Ich weiß jetzt wirklich nicht wo oder wie ich gucken soll mittels Debugger ob im dataDataSet1.LOGIN DataTable Daten Stecken weil ich da nichts gesehen habe woran ich mich orientieren könnte.

Anderseits die Meldung oben vom Login Failed macht mich jetzt etwas stutzig.


Viele Grüße


mkRE - So 13.12.15 01:50

Ich glaube ich weiß woran das problem liegen kann und zwar benutze ich VS 2012, mein MS SQL Server (Neu Installiert) ist Version 2014.
Habe jetzt bei den VS Tools die Datenbank Verbindungsparameter von (LocalDB)\v11.0 auf (LocalDB)\MSSQLLocalDB umgestellt, weil ich beim eintragen neuer Benutzerdaten in die Tabelle eine Fehlermeldung erhalten habe, dass die Versionen zu alt ist. Diese Meldung ist nun weg nach den oben genannten änderungen. Trotzdem habe ich das Problem das die Datenbank Datei "DATA" nicht mit den erhofften Benutzerdaten angezeigt wird "leer Tabelle" wie vorher. :-(


mkRE - So 13.12.15 15:23

Hallo zusammen, ich habe jetzt so lange probiert ohne Erfolg nach der oben genannten Änderung konnte ich auf einmal keine Datenbank Tabellen erstellen weil Visual Studio mit unbekanntem Fehler
neu gestartet wurde. So habe ich nach weiterer Recherche habe ich SQL Server Data Tools for Visual Studio 2012 installiert nun läuft alles wie gehabt leider die Datenbankdatei Data nicht, hab gesehen das dort in den Verbindungsdaten die unveränderlich (Grauer Hintergrund) sind (LocalDB)\v11.0 steht. Somit habe ich jetzt eine neue Datenbankdatei UserData erstellt. Die dort eingebundenen Daten werden wie gewünscht angezeigt.

Leider kommt immer mehr dazu jetzt kann ich mittels folgender Verbindungsdaten nicht mehr wie vorher mit der Datenbank verbindung aufnehmen um meine Benutzerdaten abzufragen:


C#-Quelltext
1:
SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\UserData.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True;");                    



Ich möchte die im Projekt integrierte Datenbank verwenden für Benuterdaten jedoch geht das nicht mehr :-(

Woran kann das liegen?


mkRE - Mo 14.12.15 00:44

Hallo zusammen ich melde mich noch einmal hänge immer noch an dem selben problem das ich nun nicht mehr auf meine Datenbank zugreifen kann.
Habe jetzt eine neue Anwendung gemacht mit einer neuen Datenbankanwedung. Im Debugger bleibt die Applikation mit dem Fehler stehen:

Ausnahme:Ausgelöst: "Unable to open the physical file "c:\users\user\documents\visual studio 2012\Projects\DB_Benutzeranmeldung\DB_Benutzeranmeldung\bin\Debug\Verwaltung.mdf". Operating system error 32: "32(Der Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen Prozess verwendet wird.)".
An attempt to attach an auto-named database for file c:\users\user\documents\visual studio 2012\Projects\DB_Benutzeranmeldung\DB_Benutzeranmeldung\bin\Debug\Verwaltung.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share." (System.Data.SqlClient.SqlException)
System.Data.SqlClient.SqlException wurde ausgelöst: "Unable to open the physical file "c:\users\user\documents\visual studio 2012\Projects\DB_Benutzeranmeldung\DB_Benutzeranmeldung\bin\Debug\Verwaltung.mdf". Operating system error 32: "32(Der Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen Prozess verwendet wird.)".
An attempt to attach an auto-named database for file c:\users\user\documents\visual studio 2012\Projects\DB_Benutzeranmeldung\DB_Benutzeranmeldung\bin\Debug\Verwaltung.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share."
Time: 13.12.2015 23:39:47
Thread:Hauptthread[2612]


Komme leider nicht mehr weiter und im Netz habe ich nicht viel zu dem Fehler gefunden.
Würde mich sehr freuen wenn ihr mir weiterhelfen könnt.

Viele Grüße

Danke.


Yankyy02 - Mo 14.12.15 14:51

Hallo mkRE,

eigentlich sagt dir die erste Zeile in der Fehlermeldung bereits wo du ansetzen mußt. Wenn du --> Unable to open the physical file <-- in der Suchmaschine deiner Wahl eingibst erhaltest du bereits einige Vorschläge um das Problem zu beheben. Entweder hast du keine Schreibrechte was du jedoch im Win-Explorer leicht prüfen kannst oder
warum auch immer greift bereits ein anderer Dienst/Service/Anwendung auf die Datei zu was du jedoch auch selbst überprüfen kannst bzw. mußt.

LG


mkRE - Di 15.12.15 00:46

Hallo Yankyy02,

ich danke dir für deine Antwort. Mit der Suchmaschine habe ich es auch versucht leider nichts auf die schnelle Braucubares gefunden.
Werde noch einmal schauen wie ich das problem beheben kann.

Schreibrechte habe ich geprüft sollte ok sein.
Ob etwas auf die Datei zugreift was dann der Fall sein sollte, kann ich mir grad nicht vorstellen was auf die Datei zugreifen soll?
Das ist mir ein Rätsel.

Ich melde mich wenn ich alles ausprobiert habe.

Danke.

Viele Grüße


mkRE - So 20.12.15 00:40

Hallo Yankyy02 und alle zusammen,

ich habe bis jetzt leider das problem nicht lösen können.

Im Netz viele dieser Probleme angegeben ein interessantes Thema habe ich hier gefunden bei dem ich mir ggf. Erfolg verspreche:

https://programmertoolbox.wordpress.com/2012/11/26/sql-server-unable-to-open-the-physical-file-operating-system-error-32/

Leider weiß ich nicht wo der Schreiber folgende Punkte durchführt:

1- add new connexion
2- browse to my database file in C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\MyDB


Ich habe bis jetzt noch nicht mit dem Management Studio 2014 oder auch anderen Versionen gearbeitet, Erfahrungen mit dem SQL Servern habe ich auch keine.

Brauche dringend Unterstützung :-(.

Bis jetzt habe ich auch andere Versuche durchgeführt, das ich im Management Studio die Verwaltung.mdf eingebunden habe ohne Erfolg. Sämtliche Dienste die auf die Datei Zugreifen könnten
Angehalten ohne Erfolg. Sobald ich den SQL Server Anhalte bekomme ich Anstatt der oben genannten Meldung eine andere, das der Server Angehalten ist, was auch richtig ist.

Habe alle Daten auch die SQL Server Data Tools auf dem neuesten Stand.

Ich tappe gerade im Dunkeln :-(.

Kann es sein das ich ein Problem habe weil ich MS Visual Studio 2012 verwende jedoch der SQL Server SP1 eine 2014 Version ist?
Wo ich früher den SQL Server 2012 benutzt habe bin ich nie auf solche probleme gestoßen.

Viele Grüße


Yankyy02 - So 20.12.15 01:46

Servus,

VS 2012 und SQL Server 2014 ist sicher nicht das Problem. Versuche dochmal den Lösungsvorschlag den du gefunden hast. Wäre ja in kürzester Zeit erledigt. Öffne das SQL Server Management Studio und verbinde dich damit zu deiner Instanz. Wähle deine Datenbank und führe einen rechtsklick auf die Datenbank aus um anschließend auf Tasks und Offline schalten zu wählen. Im VS fügst du dann die Datenbank wieder hinzu wie du es sonst auch machst und testet ob du dich nun wieder verbinden kannst.



LG


mkRE - Sa 26.12.15 21:07

Hallo Yankyy02,

ich muss wirklich sagen das ich nun alles mögliche versucht habe die Datenbank anzusprechen.
Auch mit der zuletzt genannten Lösung.

Jedoch tappe ich immer wieder in weitere Meldungen. Zurzeit hänge ich an folgender Meldung:
Zitat:
Message: Cannot open user default datavase. Login failed.
LineNumber: 65536
Source: .Net SqlClient Data Provider
Procedure:
Index #1
Message: Login failed for 'xxxxx\User'.
....
....

Ich habe aber für die Datenbankdatei keine User Daten angegeben und bin als Administrator angemeldet.
Verstehe das nicht.

Was mich sehr verwirrt, ist das ich auf den SQL Server 2008 ganz normal zugreifen konnte.
Einmal habe ich diese Applikation auf einem fremd PC ausprobiert, dort reichte nur LocalDB zu installieren
und es lief alles. Woran kann es den liegen das es bei 2014 auf einmal solche probleme gibt?

Würde mich sehr freuen wenn ich noch Unterstützung erhalte um aus diesem "Fehler" herauszukommen.

Vielen Herzlichen Dank.

mkRE

Moderiert von user profile iconTh69: Quote-Tags hinzugefügt


Yankyy02 - Sa 26.12.15 23:40

Hohoho,

vorab schonmal sorry aber über die Weihnachtsfeiertage ist der Alkoholspiegel etwas höher! :D Die Fehlermeldung besagt das der angegebene User sich nicht anmelden kann. Die Frage ist nun welche Anmeldemethode du bei deinem Server zugelassen hast und wie dein Connection String mittlerweile aussieht. Was mich ein wenig verwirrt ist das du einerseits von einer LocalDB sprichst und andererseits Probleme mit dem SQLServer hast!

LG


mkRE - So 27.12.15 00:20

Hallo Yankee02,

lass es dir gut gehen ein Alkoholreset muss auch mal sein :-).

Mein Ziel ist es eine vorherige Datenbankdatei anzusprechen. Mittlerweile habe ich eine neue Test Applikation erstellt mit einer Datenbankdatei Verwalten.mdf.
Es handelt sich um eine einfache Datenbankanwendung in Visual Studio 2012.

Mein Connection String sieht folgendermaßen aus:

C#-Quelltext
1:
SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\User\Documents\Verwalten.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True;");                    

und vorher so:

C#-Quelltext
1:
SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Verwalten.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True;");                    

Den MSQL Server 2014 habe ich seit kurzem installiert wo ich das alte Programm wieder testen wollte.
Ich möchte ja keine probleme mit dem SQL Server haben, vielleicht versuche ich mehr zu machen als ich brauche :-(.

Viele Grüße

mkRE

Moderiert von user profile iconTh69: C#-Tags hinzugefügt


mkRE - So 27.12.15 03:16

Hallo Yankyy02,

ich melde mich noch einmal mit neuen Erkentnissen zu meinem Problem.
Habe jetzt einmal mit dem Management Studio eine einfache Datenbank Datei erstellt mit dem Namen Test.

Connection String 1:

C#-Quelltext
1:
SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Program Files\Microsoft SQL Server\MSSQL12.SQLEXPRESS\MSSQL\DATA\Test.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True;");                    

Sobald ich mit dem Connection String auf die Datenbank zugreifen möchte, dann erhalte ich folgende Meldung wie oben beschrieben:
Zitat:
Message: Cannot open user default datavase. Login failed.
LineNumber: 65536
Source: .Net SqlClient Data Provider
Procedure:
Index #1
Message: Login failed for 'xxxxx\User'.
....
....

Daraufhin habe ich im Management Studio unter Tasks die Datenbank Offline geschaltet und der Zugriff funktioniert einwandfrei.
Allerdings habe ich hier vorher die Datenbankdatei samt log file Volle Benutzerzugriffe erteilt.

Connection String 2:

C#-Quelltext
1:
SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Test.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True;");                    

Als neue Datenquelle habe ich die neu erstellte Datenbank "Test" in Visual Studio Projekt eingebunden.
Nun möchte ich mich mit der Datenbank "Test" verbinden die im Visual Studio Projekt integriert ist, jedoch kommt wieder die Fehlermeldung " Unable to open physical file ...".

Das kann doch nicht sein?

Ich gehe jetzt mal schlafen morgen gehe ich dem weiter auf die spur.

Bin Dankbar über jeden Tipp.

Viele Grüße

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Moderiert von user profile iconTh69: Quote-Tags hinzugefügt


Yankyy02 - Mo 28.12.15 01:14

Servus,

sorry für die Abstinenz aber das ist der Feiertagsstress! :lol: Als nächsten Hinweis hätte ich für dich das dein ConnectionString nicht ganz ok ist. Bei einer Attached DB musst du Database=dbname angeben. Warum das so ist steht auf der folgenden Seite beschrieben ..... http://www.connectionstrings.com/sqlconnection/ Im Bereich: Attach a database file on connect to a local SQL Server Express instance. Sag bescheid ob es funktioniert hat.

LG


mkRE - Di 29.12.15 22:30

Hallo Yankyy02,

kein Problem ich freue mich das mich jemand unterstützen möchte. Bin dir da sehr dankbar.

Ich versuche mich gerade damit auseinander zu setzen und überlege wie ich Database = dbname in mein Connection String einbinde :-).
Die Beispiele verwirren mich etwas im link.

Viele Grüße

mkRE


mkRE - Di 29.12.15 23:21

Hallo Yankyy02,

so ich habe mal einen anderen Versuch gestartet und zwar mal aus den Eigenschaften der Test.mdf Datenbank den Connection String bzw. Verbindungszeichenfolge kopiert
und wie folgt umgebastelt:


C#-Quelltext
1:
SqlConnection con = new SqlConnection(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Test.mdf;Integrated Security=True;Connect Timeout=30");                    


Jetzt funktioniert die Verbindung puuuuhhhhhhhh :-)


Aber ehrlich gesagt wie soll man da selber darauf kommen einen funktionierenden Connection String zu schreiben?
Wo finde ich Einstiegsmateriel mit konkreten Beispielen zu Connection Strings ein guter Link oder eine PDF wäre echt super!

Dein Link finde ich auch super ohne Frage aber kannst du mir ggf. aus einem Beispiel aus deinem Link ein reales Beispiel zeigen?

Es geht um folgendes z.B.:

Trusted Connection

C#-Quelltext
1:
Server=myServerAddress;Database=myDataBase;Trusted_Connection=True;                    




Viele Grüße und vielen Dank!!


Yankyy02 - Di 29.12.15 23:41

Hallo,

zuerst freut es mich mal das du es nun geschafft hast. Zu deiner Frage bezüglich Trusted_Connection .... das ist ein Synonym für integrated security wie du es bereits schon verwendest. Schau dir mal die ConnectionStringBuilder Klassen bzw. deren Eigenschaften an dann wird's dir sicher um einiges verständlicher sein. Ausserdem finde ich es übersichtlicher als den gesamten ConnectionString in einem nur durch Semikolons getrennt zu betrachten.

Ich kann dir das Buch Datenbank-Programmierung mit Visual C# 2012 empfehlen ...... http://www.amazon.de/Datenbank-Programmierung-Visual-2012-E-Book-%C2%A0Anwendungsbeispiele/dp/386645466X/ref=sr_1_4?s=books&ie=UTF8&qid=1451425131&sr=1-4

LG


mkRE - Mi 30.12.15 01:33

Yankyy02,

ich danke dir für deine Tipps und möchte das ganze auch gerne übersichtlicher machen soweit es geht, mag es auch nicht so eingequetscht.
Zwar war es ein kleiner Erfolg und nebenbei habe ich zum erstenmal auch mit dem SQL Server Management Studio gearbeitet :-).

Falls es hierzu noch Probleme geben wird schreibe ich noch was. :wink:

Vielen Dank


Th69 - Mi 30.12.15 11:16

Da gibt es eine super Seite: The Connection Strings Reference [http://www.connectionstrings.com/] ;-)
Jeder Datenbank-Hersteller hat da seine eigenen Parameter definiert, darum kommt man ohne Doku von alleine auch nicht weiter.

Und hier explizit die .NET Framework Data Provider for SQL Server connection strings [http://www.connectionstrings.com/sqlconnection/].

Edit: habe jetzt erst gesehen, daß Yankyy02 ja schon den Link gepostet hat (hatte vorher nur den Link zum "Datenbank-Programmierung mit Visual C# 2012" gesehen) - ist wohl noch zu früh am Morgen...


mkRE - Do 31.12.15 18:51

Hallo Th69,

danke der Link ist auch ganz gut!
Werde mal alle bei mir möglichen ConnectionStrings ausprobieren wird ein interessantes Training :-).

Viele Grüße

mkRE


mkRE - So 10.01.16 02:11

Hallo zusammen,

ich wollte nochmal etwas fragen es wäre eine Erweiterung der eigentlichen Anfangsfrage.

Wie kann ich am elegantesten bei meiner Anmeldung an die Datenbank unterscheiden ob es sich bei dem Angemeldeten um ein Administrator mit erweiterten Möglichkeiten oder ob es sich um einen Standard User handelt?

Mir schwebt da vor Die Datenbank mir einem weiteren Feld zu erweitern wo noch zu den Benutzerdaten angegeben wird ob er ein User oder Admin ist.

- Uder_ID - Benutzerrechte - Benutzername - Passwort -

Leider komme ich nicht darauf wie ich es am elegantesten Abfragen soll.

Würde mich hierbei um einige Tipps freuen.

Vielen Dank.


Yankyy02 - So 10.01.16 12:59

Servus,

ich hoffe ich habe die Frage richtig verstanden ...... du möchtest prüfen ob der User am lokalen PC in der Gruppe der Administratoren ist bzw. über diese Rechte verfügt? Wenn dem so ist solltest du dir die WindowsPrincipal [https://msdn.microsoft.com/de-de/library/system.security.principal.windowsprincipal%28v=vs.110%29.aspx]-Klasse ansehen. Mit der Methode IsInRole(SecurityIdentifier) der Klasse kannst du das prüfen. Ich würde mir dazu eine eigene Methode schreiben die true oder false zurück gibt ob es sich um einen Admin handelt.

LG

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Moderiert von user profile iconTh69: URL-Titel hinzugefügt.


mkRE - Mo 11.01.16 00:24

Hallo Yankyy02,

freue mich über deine Antwort die mich auf einer weitere Idee gebracht hat und sicherlich von nutzen sein wird!
Leider lag meine Vorstellung wo anders vielleicht etwas einfacher und zwar soll in der Datenbank zu jedem User noch eine User ID und Benutzerrechte zu dem Usernamen und Passwort eingegeben werden.

Im Feld Benutzerrechte steht dann entweder User oder Admin.

Ich möchte nun Abfragen ob der Username und das Passwort das sich anmelden will erweiterte Rechte "Admin der Anwendung" nur für die Anwendung hat oder nicht.
Falls es sich um einen Admin handelt, werden noch weitere möglichkeiten in der Anwendung freigeschaltet z.B. kann der jenige weitere Benutzernamen eintragen usw.

Ich hab leider keine Idee wie ich das Abfragen soll.

Bis jetzt habe ich von dir ganz am Anfang gelernt wie man am besten den Benutzernamen und das Passwort abfragt mit dem SQLDataReader und hier versuchte ich gestern auch etwas zu finden.

Parallel versuche ich noch eine Lösung zu finden.
Habe zwar gestern die Anmeldung einmal für einen Admin und die andere für einen User gemacht jeweils ein Button, aber das gefällt mir absolut gar nicht
und habs auch wieder entfernt.


Viele Grüße und Danke für deine Unterstützung.


Yankyy02 - Mo 11.01.16 21:39

Servus,

um das Rad nicht neu zu erfinden hier ein Link der dich in die richtige Richtung lenken sollte. User Login [http://www.codeproject.com/Articles/29853/User-Login-For-WinForm-Applications].
Als Alternative wenn du nicht unter Windows-Benutzer unterscheiden möchtest sonder explicit für deine Anwendung würde sich ein Bool-Feld in deiner Datenbank bzw. in deiner User-Tabelle anbieten das du bei der Anmeldung abfragst und dir in deiner Anwendung als Eigenschaft merkst. Sobald ein User eine Funktion aufruft die nur ein Admin darf prüfst du ob der Angemeldete Benutzer ein Admin ist.

LG


mkRE - Do 14.01.16 00:24

Hallo Yankyy02 sorry für die Verspätung hatte einiges um die Ohren.

An die User Login Beispiel Applikation gehe ich mal am Wochenende an und melde mich dann mit Ergebnissen.

Der Tipp mit dem Bool-Feld ist super habe gar nicht daran gedacht ich wollte das ganze ursprünglich auf die Schlüsselwörter User oder Admin abfragen.

Es geht auch Einfacher so wie ich es grad sehe :D .

Melde mich auf jedenfall mit Ergebnissen :!: oder auch Problemen :?: .

Viele Grüße


mkRE - Do 14.01.16 00:50

Hallo Yankyy02 ich melde mich doch noch mal.

user profile iconYankyy02 hat folgendes geschrieben Zum zitierten Posting springen:
Servus,
Als Alternative wenn du nicht unter Windows-Benutzer unterscheiden möchtest sonder explicit für deine Anwendung würde sich ein Bool-Feld in deiner Datenbank bzw. in deiner User-Tabelle anbieten das du bei der Anmeldung abfragst ....


Hier war mein eigentliches Problem, das ich nicht weiß wie ich unterscheiden kann bei der Anmeldung ob es ein Admin oder User ist nur explizit bei der Anwendung in meiner User-Tabelle.
Mittels SQLDataReader. Der Datenbank weg wäre mir aktuell lieber obwohl die Windows-Benutzer Thematik in den meisten Anwendungen mehr sinn machen kann.

Naja ich schaue mal was das Wochenende für Erfolge bringt :?.

Danke und viele Grüße


Yankyy02 - So 17.01.16 01:24

Hallo mkRE,

quick and dirty wie man so schön sagt würde es eben dann über ein zusätzliches Feld in deiner Datenbank gehen. Als Spaltenbezeichner zb. Administrator und als Datentyp würde sich Bit anbieten.
Wenn du dir eine statische Klasse zb. AccessControl mit einer statischen Property IsAdmin erstellst kannst du diese Property bei der Abfrage des Benutzers und zugehörigen Passwortes setzen wenn die Anmeldung erfolgreich war. Bevor dann eine Aktion ausgeführt wird die nur von einem Admin ausgeführt werden darf kannst du mit AccessControl.IsAdmin prüfen ob der User dazu berechtigt ist.


C#-Quelltext
1:
AccessControl.IsAdmin = Convert.ToBoolean(reader["Administrator"]);                    


LG


mkRE - So 17.01.16 17:22

Hallo Yankyy02,

ich habe gedacht das ich dieses Wochenende ans Programmieren gehen kann leider hat es nicht geklappt :(.
Danke für den Tipp oben wie versprochen halte ich dich auf dem Laufenden ob ich damit klar gekommen bin.

Das will ich hinbekommen und die Datenbank Testanwendung abschließen um an ein Größeres Projekt ranzugehen was ich plane.

P.S. die Windows Administrations Beispielanwendung ist klasse und auf jedenfall findet diese Variante auch Ihren nutzen!!

Viele Grüße


mkRE - Sa 30.01.16 01:52

Hallo Yankyy02,

ich bin heute mal endlich an das Projekt ran gekommen, momentan viel zu tun :-)
Es funktioniert nun alles so wie es gedacht war.
Ich habe zum Probieren als probe erstmal in der Datenbank das Administationsfeld Admin oder User als string gewählt.

Es funktioniert zwar alles, aber ich habe ein problem gehabt beim geöffneten DataReader zwei mal ein Command auszuführen.
Weil ich zuerst einmal prüfen wollte ob die Benutzerdaten Name und Passwort ok sind und dann im nächsten Schritt ob es sich um einen Admin handelt.
Dazu musste ich die MARS Methode nutzen, jedoch funktioniert diese nur bei SQL Datenbanken wie ich gelesen habe.

Meine Frage nun dazu ist, wie könnte man es noch anders lösen?

Hier einmal der Code der Methode der Klasse AccesControl:



C#-Quelltext
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:
        private static string GetConnectionString()
        {
            return "Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\\UserData.mdf;Integrated Security=True;Connect Timeout=30; MultipleActiveResultSets=True";
        }


        public bool Access(string username, string password)
        {
            SqlDataReader re_access = null;
            StringBuilder errorMessages = new StringBuilder();
           
            using (SqlConnection con = new SqlConnection(@GetConnectionString()))
            {
                try
                {
                    SqlCommand cmd = new SqlCommand("Select * From Usertable where Username='" + username + "' and Password = '" + password + "'", con);
                    SqlCommand cmd_access = new SqlCommand("Select * From Usertable where Username='" + username + "' and Password = '" + password + "' and Access='" + "Admin" + "'", con);

                    con.Open();

                    using (SqlDataReader re = cmd.ExecuteReader())
                    {
                        while (re.Read())
                        {
                            access = true;

                            re_access = cmd_access.ExecuteReader();
                            using (re_access)
                            {
                                while (re_access.Read())
                                {
                                    isAdmin = "Admin";
                                }
                            }
                        }
                    }

                    con.Close();
                }
                catch (SqlException ex)
                {
                    for (int i = 0; i < ex.Errors.Count; i++)
                    {
                        errorMessages.Append("Index #" + i + "\n" +
                            "Message: " + ex.Errors[i].Message + "\n" +
                            "LineNumber: " + ex.Errors[i].LineNumber + "\n" +
                            "Source: " + ex.Errors[i].Source + "\n" +
                            "Procedure: " + ex.Errors[i].Procedure + "\n");
                    }
                    access = false;
                    System.Windows.Forms.MessageBox.Show(errorMessages.ToString());
                    con.Close();
                }
            }
            return access;           
        }


und hier ein Auszug wo die Methode angewendet wird bzw. wofür:


C#-Quelltext
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:
private void btnAnmelden_Click(object sender, EventArgs e)
        {

            AccessControl access = new AccessControl();

                if (access.Access(txtUsername.Text, txtPasswort.Text) && AccessControl.IsAdmin == "Admin")
                {
                    frmBTGDatabase.label_1.Text = "Angemeldet Admin";
                    frmBTGDatabase.button_1.Enabled = true;
                    frmBTGDatabase.button_2.Enabled = true;
                    frmBTGDatabase.button_3.Enabled = true;
                    frmBTGDatabase.button_4.Enabled = true;
                    frmBTGDatabase.button_5.Enabled = true;
                    frmBTGDatabase.button_6.Enabled = true;
                    this.Close();
                }
                else if (access.Access(txtUsername.Text, txtPasswort.Text))
                {
                    frmBTGDatabase.label_1.Text = "Angemeldet User";
                    frmBTGDatabase.button_1.Enabled = true;
                    frmBTGDatabase.button_2.Enabled = true;
                    frmBTGDatabase.button_3.Enabled = true;
                    frmBTGDatabase.button_4.Enabled = true;
                    frmBTGDatabase.button_5.Enabled = true;
                    this.Close();
                }
                else
                {
                    MessageBox.Show("Benutzername oder Passwort falsch!");
                    this.Close();
                }
        }


P.S. Es handelt sich hier um eine frühere Idee, jedoch finde ich deine Idee besser bei Jeder Aktion zu prüfen ob die Admin oder User Berechtigungen hat.

Viele Grüße


Ralf Jansen - Sa 30.01.16 13:12

a.) Wieso benutzt du 2 DataReader? Das erste Statement würde dir in den Daten bereits den Inhalt des Access Feld liefern du müsstest es einfach nur auslesen (re["Access"]).
b.) Wieso benutzt du überhaupt einen DateReader? Erwartest du von der Abfrage jemals mehr als 1 Ergebnis?
c.) Für die Technik erstmal weniger relevant. Aber willst du wirklich das Passwort als Klartext ablegen? Das solltest du, sobald das so funktioniert wie du willst, umstellen.

Unter der Annahme das du nur wissen willst ob der User Zugang bekommt und wenn ja welchen dann würde ich das folgendermassen machen.
a.) Den Zugang über strings zu regeln finde ich merkwürdig ich würde einen Enum verwenden und in der Datenbank als Zahlentyp (access also als nicht nullable int) darstellen. Das funktioniert aber mit strings auch.
b.) Das ErrorHandling gehört für mich nicht in deine AccessControl Klasse rein. Insbesondere wenn das Errorhandling ein einfaches MessageBox Show ist (meiner Meinung nach also eher kein ErrorHandling sondern ein ErrorAufUserAbwälzing ;) ). Die Methode/Klasse ist eigentlich unabhängig von der UI Technik. Sie würde genauso in einer Webanwendung funktionieren. Di eunabhängig sollte man nicht durch unnötige Abhängigkeiten kaputt machen. Was Sinn machen kann wäre das fangen der SqlException und umpacken in eine eigene die die Aufbereitung der ErrorMEssage beherrscht und dann diese Exception werfen anstatt der SqlException.


C#-Quelltext
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:
[Flags]
public enum Access
{
    None = 0x0,
    Login = 0x1,
    Admin = 0xFF
}

public static Access? GetAccess(string username, string password)
{
    using (var con = new SqlConnection(GetConnectionString()))
    {
        con.Open();
        using (var cmd = con.CreateCommand())
        {
            cmd.CommandText = @"Select Access From Usertable where Username=@username and Password=@password";
            cmd.Parameters.AddWithValue("@username", username);
            cmd.Parameters.AddWithValue("@password", password);

            int? result = cmd.ExecuteScalar() as int?;

            if (!result.HasValue)
                return null// login failed no access

            return (Access)result.Value;
        }
    }
}

// Aufruf
var access = AccessControl.GetAccess(txtUsername.Text, txtPasswort.Text);

if (access.HasValue)
{
    if (access.Value.HasFlag(Access.Admin))
    {
        // admin
    }
    else
    {
        // anderer Zugang
    }
}
else
{
    // kein Zugang 
}


mkRE - Sa 30.01.16 20:31

Hallo Ralf,

vielen Dank für deine Antwort hier kommen meine Antworten zu deinen Fragen:

a.) Ich hab es noch nicht herausgefunden wie ich aus einem DataRead einzelne Werte zusätzlich abfragen kann z.B. in dem Fall den Wert in der Datenbank Spalte Access.
So kam ich zuerst auf die Idee zwei command Befehle zu schreiben. Dabei bin ich auf das Problem gestoßen das ich den Reader nicht zwei mal nacheinander anwenden konnte.
So habe ich im Netz nach einer möglichkeit gesucht und diese MARS Methode auf den Seiten von Windows gefunden. Dort wurde auch mit zwei DataReader ein Beispiel gezeigt. Das war der Grund.
Wie frage ich den aber Einzelne Werte ab bzw. das einfache auslesen (re["Access"]).
In erster Linie möchte ich einmal nur sehen ob der User auch Adminrechte hat, der Lösungsvorschlag von Yankyy02 gefällt mir sehr, dort war aber die rede von einem Bool, das wollte ich auch noch
nachträglich so realisieren.
[i]
Gucke heute Abend nochmal danach in dem Program wo du es genau meinst. Mir sind die Befehle noch nicht ganz klar bzw. vielleicht bei den vielen Hilfen übersehen.
b.) Bei dieser Anwendung erwarte ich nur 1 Ergebnis. Den DataReader habe ich gewählt, weil alle Beispiele die ich vor ca. 2 Jahren zum Thema Benutzeranmeldung gefunden habe den DataReader verwendet
haben und nun ist das bei mir hängen geblieben.
c.)Meinst du den Text als Klartext in der Datenbank? Bei der Eingabe über die Anwendung ist der Passwort Text nicht erkennbar. In der Datenbank momentan ja jedoch möchte ich das Passwort nicht als
Klartext zu erkennen geben und in Form von Sternchen anzeigen lassen. Hoffe ich habe deine Frage richtig verstanden?


Ja genau hierbei möchte ich nur wissen ob der User Zugang hat und natürlich für welchen Bereich.
Es gibt so viele Möglichkeiten und dein Vorschlag ist auch eine gute Idee. Leider fallen mir nicht alle möglichen Methodiken ein die man nutzen könnte es gibt sicherlich auch noch ganz andere Wege.
(Ich frage mich immer woher ihr das alles wisst :) :oops: ist positiv gemeint).

Zu dem Error Handling danke für den Tipp, habe mir schon gedacht das es jemand anmeckert das es sich in der AccessControl Klasse befindet :D, muss mir noch was dazu ausdenken.

Viele Grüße

mkRE


mkRE - Sa 30.01.16 20:43

Ich sehe gerade wer lesen kann ist klar im Vorteil :-) Yankyy02 hat es auch schon beschrieben mano tut mir leid.
Also so kann ich einzeln auf Werte im Reader abfragen.

Beispiel von Yankyy02


C#-Quelltext
1:
AccessControl.IsAdmin = Convert.ToBoolean(reader["Administrator"]);                    


Ich muss mich vielmals entschuldigen bei euch beiden, das ich das gestern übersehen habe.

Viele Grüße


mkRE - Mi 03.02.16 01:00

Hallo zusammen und danke besonders an Yankyy02 und Ralf Jansen für die Hilfe bei dem Thema.

Das ganze funktioniert jetzt und ist für mich für die Anwendung ausreichend.
Ich habe es bei der Anwendung isAdmin bei einem String gelassen jedoch werde ich das bei einer nächsten Anwendung mit einem Bool Feld erledigen.

Unten habe ich mal den Code der AccessControl Klasse beigefügt, vielleicht interessiert es ein paar Einsteiger die einen Lösungsansatz suchen.
Für weitere Tipps oder Anmerkungen dazu würde ich mich freuen.


C#-Quelltext
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:
87:
88:
89:
namespace BTG_Database
{
    class AccessControl
    {
        private static bool access = false;
        private static string isAdmin = "";

        private bool error = false;
        private string errormessage = "";
        
        public static bool AccessSuccessfull
        {
            get { return access; }
        }

        public static string AccessIsAdmin
        {
            get { return isAdmin; }
        }

        public bool AccesError
        {
            get { return error; }
        }

        public string AccessErrorMessage
        {
            get { return errormessage; }
        }

        private static string GetConnectionString()
        {
            return "Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\\UserData.mdf;Integrated Security=True;Connect Timeout=30";
        }

        public bool Access(string username, string password)
        {
            
          StringBuilder errorMessages = new StringBuilder();
          using(SqlConnection con = new SqlConnection(@GetConnectionString()))
          {
            try
            {                    
                    SqlCommand cmd = new SqlCommand("Select * From Usertable where Username='" + username + "' and Password = '" + password + "'", con);
                    con.Open();

                    SqlDataReader re = cmd.ExecuteReader();
                
                if (re.Read())
                    {
                        
                        access = true;
                        isAdmin = Convert.ToString(re["Access"]);
                    }
                    else
                    {
                        access = false;
                    }

                    con.Close();

             }
            catch (SqlException ex)
             {
               error = true;
               access = false;
               con.Close();
   
               for (int i = 0; i < ex.Errors.Count; i++)
               {
                   errorMessages.Append("Index #" + i + "\n" +
                       "Message: " + ex.Errors[i].Message + "\n" +
                       "LineNumber: " + ex.Errors[i].LineNumber + "\n" +
                       "Source: " + ex.Errors[i].Source + "\n" +
                       "Procedure: " + ex.Errors[i].Procedure + "\n");
               }               
               errormessage = errorMessages.ToString();              
            }
          }
                    return access;           
        }

        public void Logout()
        {
            isAdmin = "";
            access = false;
        }
    }
}


Viele Grüße und Danke


Th69 - Mi 03.02.16 10:36

Noch ein Tipp:
Benutze dringendst SqlParameter (anstatt dem Zusammensetzen von SQL-Strings mittels ') - Stichwort: SQL-Injection [https://de.wikipedia.org/wiki/SQL-Injection]!