Good afternoon, I would like you to help me. I am logging in 3 layers since I am capturing my values in a SqlDataReader.
This is my DataCap.
public void LogeoUsuario(string cboAgencia, string clave, string usuario)
{
using (SqlConnection con2 = new SqlConnection(connectionString))
{
con2.Open();
using (SqlCommand cmd2 = new SqlCommand("SP_TTareasLogeo", con2))
{
cmd2.CommandType = CommandType.StoredProcedure;
cmd2.Parameters.Add("@oficina", SqlDbType.VarChar).Value = cboAgencia;
cmd2.Parameters.Add("@pass", SqlDbType.VarChar).Value = clave;
cmd2.Parameters.Add("@usernamecomprobante", SqlDbType.VarChar).Value = usuario;
cmd2.ExecuteNonQuery();
}
}
}
My Business layer:
public void LogeoUsuario(string cboAgencia, string clave, string usuario)
{
D_Usuario Usuario = new D_Usuario();
Usuario.LogeoUsuario(cboAgencia, clave, usuario);
}
My Presentation Layer:
protected void btnLogeo_Click(object sender, EventArgs e)
{
N_Usuario Usuario = new N_Usuario();
Usuario.LogeoUsuario(cboAgenciaUsuario.Text, txtClaveAgencia.Text, txtUsuario.Text);
SqlDataReader rd = cmd.ExecuteReader();
if (rd.HasRows)
{
rd.Read();
lblidperfil.Text = rd["perfil"].ToString();
lbloficinass.Text = rd["oficina"].ToString();
lblusuario.Text = rd["NombreCompleto"].ToString();
lblidusuariologin.Text = rd["idusuario"].ToString();
idoficinausuario.Text = rd["idoficina"].ToString();
lblinfo.Text = "Autosizado.";
FormsAuthentication.RedirectFromLoginPage(lblidperfil.Text, true);
FormsAuthentication.RedirectFromLoginPage(lbloficinass.Text, true);
FormsAuthentication.RedirectFromLoginPage(lblusuario.Text, true);
FormsAuthentication.RedirectFromLoginPage(lblidusuariologin.Text, true);
FormsAuthentication.RedirectFromLoginPage(idoficinausuario.Text, true);
Session["perfil"] = lblidperfil.Text;
Session["oficina"] = lbloficinass.Text;
Session["NombreCompleto"] = lblusuario.Text;
Session["idusuario"] = lblidusuariologin.Text;
Session["idoficina"] = idoficinausuario.Text;
if (int.Parse(lblidperfil.Text) == 3)
{
Response.Redirect("FrmAgenciaLima.aspx");
}
else if (int.Parse(lblidperfil.Text) == 4)
{
if (rd.HasRows)
{
rd.Read();
lblidperfil.Text = rd["perfil"].ToString();
lbloficinass.Text = rd["oficina"].ToString();
lblusuario.Text = rd["NombreCompleto"].ToString();
lblidusuariologin.Text = rd["idusuario"].ToString();
idoficinausuario.Text = rd["idoficina"].ToString();
lblinfo.Text = "Autosizado.";
FormsAuthentication.RedirectFromLoginPage(lblidperfil.Text, true);
FormsAuthentication.RedirectFromLoginPage(lbloficinass.Text, true);
FormsAuthentication.RedirectFromLoginPage(lblusuario.Text, true);
FormsAuthentication.RedirectFromLoginPage(lblidusuariologin.Text, true);
FormsAuthentication.RedirectFromLoginPage(idoficinausuario.Text, true);
Session["perfil"] = lblidperfil.Text;
Session["oficina"] = lbloficinass.Text;
Session["NombreCompleto"] = lblusuario.Text;
Session["idusuario"] = lblidusuariologin.Text;
Session["idoficina"] = idoficinausuario.Text;
}
Response.Redirect("defaultSiguiente.aspx");
}
else if (int.Parse(lblidperfil.Text) == 1)
{
if (rd.HasRows)
{
rd.Read();
lblidperfil.Text = rd["perfil"].ToString();
lbloficinass.Text = rd["oficina"].ToString();
lblusuario.Text = rd["NombreCompleto"].ToString();
lblidusuariologin.Text = rd["idusuario"].ToString();
idoficinausuario.Text = rd["idoficina"].ToString();
lblinfo.Text = "Autosizado.";
FormsAuthentication.RedirectFromLoginPage(lblidperfil.Text, true);
FormsAuthentication.RedirectFromLoginPage(lbloficinass.Text, true);
FormsAuthentication.RedirectFromLoginPage(lblusuario.Text, true);
FormsAuthentication.RedirectFromLoginPage(lblidusuariologin.Text, true);
FormsAuthentication.RedirectFromLoginPage(idoficinausuario.Text, true);
Session["perfil"] = lblidperfil.Text;
Session["oficina"] = lbloficinass.Text;
Session["NombreCompleto"] = lblusuario.Text;
Session["idusuario"] = lblidusuariologin.Text;
Session["idoficina"] = idoficinausuario.Text;
}
Response.Redirect("defaulthost.aspx");
}
else
{
Response.Redirect("default.aspx");
}
}
Mistake :
I see a conceptual problem: If you are using the 3-layer layout (data, business, presentation) why are you trying to use a
SqlDataReader
in your presentation layer?In any case, your data layer should take care of reading the result and placing it in some structure or object to be used by your business layer. The presentation layer then fetches the data from the business layer to present to the user.
@Pierro you are using a cmd object that you don't send as an output parameter between the lower layers.
In addition, cmd does not send it as a result of the layers (and you should not) it is recommended that between layers you "bubble" (here I mean what happens from layer to layer) business objects / dto (entities). That is to say that in this particular case in the data layer you return a User (with its respective properties) So the data layer is only responsible for knowing "where to go to look for and how to retrieve that data". In this case they are commands on a SQL db but it could search in a webservice, api's, authenticate in a social network, etc. That is why it is recommended not to send the cmd as a response, but rather an object that you retrieve or need.
Even to pass data to lower layers you could also pass objects and not large amounts of parameters (not because nothing else can be done by coupling again)... Imagine sending a model/object that has 3 properties
It would be in your example that you build the User and return said object or null. So in the business layer or even the presentation it checks if the object is null or you already have the user
Also, and not least the password issue that you comment on in the code you use... so that it is not a simple String, I recommend you use SecureString, which is a little more secure. Take a look at how this type of object helps to store the password string
I hope it helps or guides you.
I see several details that must be corrected, I will list them and later I will put the code segments with the necessary adjustments:
if-else-if
since all the declared conditions are always being evaluated, for this case, it is better to use aswitch()
.For this case, we will rely on a class, which will have the necessary properties to be able to assign both the user data and the profile data.
Presentation layer:
Business Layer:
Data layer:
As you will see, now you will also have to modify the Stored Procedure
SP_TTareasLogeo
, that is, at the beginning, validate that the username and password are valid, and if the result is positive, you must return aDataSet
with the field namesIdUsuario
,NombreUsuario
,NombreCompleto
,Perfil
,IdOficina
andOficina
.Note: the code is not tested, it is possible that you will get errors in its implementation.
To read the instance from
SqlCommand
within the methodbtnLogeo_Click()
, you'll need to define it at the class level:get the value:
and this way you can use it inside the method:
It is important to tell you that if you are structuring your project in layers, in your presentation layer you should not execute commands.