andreas_lindhMedlem sedan jan. 20011 091 inlägg
Jag har tittat lite i den här tråden
http://www.webforum.nu/showthread.php?s=&postid=520173#post520173
För att testa det här har jag kopierat koden som P skrivit
jag har skapat en funktion i BusinessL
Public Function Login(Username as string, password as string)
Return(RetriveDataReader("SELECT * FROM users WHERE password = '"& password &"' and username='" & username &"' "))
End Function
Hur gör jag nu för att använda den här datareadern på aspx sidan?
PatrikBMedlem sedan mars 20002 713 inlägg
En datareader bör (ska) inte användas på .aspx-sidan. Strider mot OOP'n.
.aspx-sidan ska "prata" med lagret "närmast till höger" (BusinessLayer) som i sin tur "pratar med lagret närmast till höger" (BusinessDataLayer/DataLayer).
rent tekniskt:
Dim _dr As SqlDataReader = Login(Username, Password)
MEN!!!
Enligt mig ska denna metod egentligen inte returnera något annat än ett Booleskt värde (True/False) beroende på om inloggningen är lyckad eller inte.
Public Function Login(Username as string, password as string) As Boolean
Dim _dr As SqlDataReader = RetriveDataReader("SELECT * FROM users WHERE password = '"& password &"' and username='" & username &"' ")
Dim isMember As Boolean = _dr.Read()
_dr.Close()
Return isMember
End Function
cya,
PatrikB
andreas_lindhMedlem sedan jan. 20011 091 inlägg
jag skapar ju datareadern i codebehindfilen för aspx sidan.
Ska man inte göra det? Och i så fall. Var ska man skapa datareadern?
andreas_lindhMedlem sedan jan. 20011 091 inlägg
Jag har testat det där nu men får ett felmeddelande
Dim objBusinessL As BusinessL = New BusinessL()
Dim _dr As OdbcDataReader = objBusinessL.Login(FixaTecken(tbUsername.Text), FixaTecken(tbPassword.Text))
If _dr.Read Then
Session("user") = _dr("id")
Response.Redirect("inloggad.aspx")
Else
End If
Felet
Exception Details: System.InvalidOperationException: Invalid attempt to Read when reader is closed.
Source Error:
Line 52: Dim _dr As OdbcDataReader = objBusinessL.Login(FixaTecken(tbUsername.Text), FixaTecken(tbPassword.Text))
Line 53:
Line 54: If _dr.Read Then
Line 55: Session("user") = _dr("id")
Line 56: Response.Redirect("inloggad.aspx")
Source File: d:\inetpub\wwwroot\gService\default.aspx.vb Line: 54
WalkerMedlem sedan okt. 2002185 inlägg
andreas_lindh skrev:
jag skapar ju datareadern i codebehindfilen för aspx sidan.
Ska man inte göra det? Och i så fall. Var ska man skapa datareadern?
tanken är att datalagert, dit räknas en datareader skall endast finnas i datalagret. Datareadern skall sedan fylla ett objekt på något sätt. Detta objekt är ditt affärslagers objekt, en del av ditt logiklager, businesslayer eller vad man kallar det för. detta objekt skickar du sedan upp till din aspx sida..
Detta är det som är renast om man skall vara OO purist. Men det kan bli en hel del overhead om du bara har ett litet projekt då du måste skapa ett userobjekt ett usermanager objekt (databaslagret).
Om man skall göra det så oo som möjligt så skulle jag göra så här. Du skapar ett User object där du har en statisk metod Login(string username, string password). denna metod anropar din usermanager och här skapar du din datareader och läser in datan om du nu behöver ett helt objekt. så i c# blir det något sånt här..
i aspx sidan..
myUser = cUser.Login(username, password);
if (myUser.IsApproved == false)
{
// felhantering
}
Då du skapar ett nytt user objekt så är detta tomt, och således så returnerar IsApproved false per default.
i din User klass..
public static User Login(string usename, string password)
{
Usermanager dal = new Usermanager();
User myUser = new User();
myUser = dal.LoadUser(username, password);
if (myUser.IsLoggedIn == false)
{
/* felhantering.. eller om du vill ha det längre upp vilket nog känns mer ok */
}
return myUser;
}
i Usermanager så skapar du datareadern som hämtar datan för det aktuella objektet och fyller det med data.
Jag tycker detta fungerar bra men det finns säkert en massa andra metoder och tekniker för att lösa detta.. Men jag tror att pricipen är korrekt..
/w
PMedlem sedan jan. 20012 107 inlägg
Walker skrev:
tanken är att datalagert, dit räknas en datareader skall endast finnas i datalagret. Datareadern skall sedan fylla ett objekt på något sätt. Detta objekt är ditt affärslagers objekt, en del av ditt logiklager, businesslayer eller vad man kallar det för.
2 skilda klasser alltså? En där dataobjektet skapas som returnerar det till affärslagret där valideringen görs?
red/citatfel
WalkerMedlem sedan okt. 2002185 inlägg
P skrev:
Walker skrev:
tanken är att datalagert, dit räknas en datareader skall endast finnas i datalagret. Datareadern skall sedan fylla ett objekt på något sätt. Detta objekt är ditt affärslagers objekt, en del av ditt logiklager, businesslayer eller vad man kallar det för.
2 skilda klasser alltså? En där dataobjektet skapas som returnerar det till affärslagret där valideringen görs?
fattar inte riktigt vad du menar.. :r
PMedlem sedan jan. 20012 107 inlägg
Typ:
Klass Data
Funktion päron()
'Make my object, dataset eller ngt
Retunerar till klass Business
End Function
Klass Business
'Hämtar från dataklassen
'Gör validering etc
Retunerar till presentationslagret
osv...
WalkerMedlem sedan okt. 2002185 inlägg
Japp två skilda klasser.. Jag brukar dock inte skapa objektet i datalagert utan jag skickar objekt som en referens till datalagret..
tex i en user klass..
public void Load(){ datalager.FillObject(this);}
Datalagret hämtar sen data från datakällan och fyller det aktuella objektet.. Men det är bara en metod, det finns massvis av andra metoder och vad som är rätt för mig kan vara helt fel för någon annan person.. tex så vet jag att en del skickar har ett connectionobject som de bollar med i logiklagret.. Detta fungerar enligt dem kanon.. jag tycker inte om det..
andreas_lindhMedlem sedan jan. 20011 091 inlägg
Nu har jag försökt göra som PatrikB sa att ha en funktion som returnerar true eller false
Public Function Login(ByVal Adress As String, ByVal password As String) As Boolean
Dim _dr As OdbcDataReader = RetriveDataReader("SELECT * FROM wmUsers WHERE password = '" & password & "' and Adress='" & Adress & "' ")
Dim isMember As Boolean = _dr.Read()
_dr.Close()
Return isMember
End Function
Men jag får fortfarande felet
System.InvalidOperationException: Invalid attempt to Read when reader is closed.
funktionen RetriveDataReader ser ut så här.
Function RetriveDataReader(ByVal SqlStatement As String)
Try
objConn.Open()
Dim Command As OdbcCommand = CreateCommand(SqlStatement)
Dim dr As OdbcDataReader = Command.ExecuteReader(CommandBehavior.CloseConnection)
objConn.Close()
Return dr
Catch Exp As OdbcException
Throw (Exp)
Finally
objConn.Close()
End Try
End Function
renholmMedlem sedan apr. 20012 048 inlägg
Du har objConn.Close() i finally vilket gör att objConn stängs innan den kommer till Login funktionen.
PatrikBMedlem sedan mars 20002 713 inlägg
När du kör:
_dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
så behöver du inte stänga connection. Det görs när du kör _dr.Close()
cya,
PatrikB
PMedlem sedan jan. 20012 107 inlägg
Kör med datatable annars. Om du använder mysql kan du kolla på p.latmask.com/CodeGenP/CodeGenP.exe, det kan hjälpa dig ( den genererar all kod som behövs)
PatrikBMedlem sedan mars 20002 713 inlägg
Har du läst Jimmy Nilssons artiklar på https://www.informit.com ?
Om inte, gör det. Just nu finns det fyra artiklar om "Data Containers" och en femte är väl på G snart, hoppas jag.
cya,
PatrikB
PMedlem sedan jan. 20012 107 inlägg
Bara jag som inte hittar artiklarna?
JosefMedlem sedan mars 20023 123 inlägg
PatrikBMedlem sedan mars 20002 713 inlägg
Det går inte att länka till artiklarna direkt.
I menyn till vänster välj "More Topics" under "Web Development".
Klicka sedan på NET i sectionen "In Articles".
Sedan heter artiklarna: Choosing Data Containers for .NET, Part 1
Totalt finns det 4 artiklar.
OK, de visar inte direkt hur man "ska göra" utan det är mer en genomgång av olika typer av DataContainers som DataSets, Hashtables etc som jag tycker att man bör läsa så man vet vad det finns för möjliga Data Containers.
cya,
PatrikB