[英]ASP.NET User Validation
我在代碼中感到困惑,我需要使用ASP.Net和存儲過程驗證UserName
和Password
,但是所有時間我都得到-1所以我該如何解決這個問題?
這是我的項目:
地毯業務:
MngUser.cs
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Data.Models;
namespace Business
{
public class MngUser
{
private string mSqlCnn;
public MngUser(string pSqlCnn)
{
mSqlCnn = pSqlCnn;
}
public ObjRespuesta AccountLogin(User MyUser)
{
ObjRespuesta resp = new ObjRespuesta();
try
{
if (string.IsNullOrEmpty(MyUser.UserName) && string.IsNullOrEmpty(MyUser.Password))
{
resp.IsError = true;
resp.NumError = 200;
resp.Mensaje = "Usuario y Contraseña Inválida";
return resp;
}
Data.Interfaces.IUser mngUser = new Data.UserEntity(mSqlCnn);
int LogResult = mngUser.Entrar(MyUser);
if (LogResult > 0)
{
resp.IsError = false;
resp.NumError = 0;
resp.Mensaje = "Error al conectar a la base de datos";
return resp;
}
else if (LogResult == -1)
{
resp.IsError = true;
resp.NumError = 201;
resp.Mensaje = "OK";
return resp;
}
}
catch (Exception ex)
{
resp.IsError = true;
resp.NumError = 400;
resp.Mensaje = ex.Message;
}
return resp;
}
}
}
地毯業務
ObjRespuesta.cs
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Business
{
public class ObjRespuesta
{
public bool IsError { get; set; }
public int NumError { get; set; }
public string Mensaje { get; set; }
}
}
地毯數據:
IUser.cs
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Data.Models;
namespace Data.Interfaces
{
public interface IUser
{
int Create(User user);
int Entrar(User user);
}
}
型號: User.cs
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Data.Models
{
public class User
{
public string UserName { get; set; }
public string Password { get; set; }
}
}
地毯業務UserEntity.cs
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Data.Interfaces;
using Data.Models;
using System.Data.SqlClient;
using System.Data;
using System.Web;
namespace Data
{
public class UserEntity:IUser, IDisposable
{
private string mSqlCnn;
private SqlCommand mSqlCommand;
private SqlConnection mSqlConnection;
public UserEntity(string SqlCnn)
{
mSqlCnn = SqlCnn;
}
private bool CreateConnection()
{
try
{
mSqlConnection = new SqlConnection(mSqlCnn);
mSqlConnection.Open();
return true;
}
catch (Exception ex)
{ throw ex; }
}
public void Dispose()
{
if (mSqlConnection != null)
{
if (mSqlConnection.State == System.Data.ConnectionState.Open)
{
mSqlConnection.Close();
mSqlConnection = null;
}
}
if (mSqlCommand != null)
{
mSqlCommand = null;
}
}
public int Entrar(User pUser)
{
int logresult = 0;
try
{
if (CreateConnection())
{
if (mSqlConnection != null && mSqlConnection.State != ConnectionState.Open)
{
mSqlConnection.Open();
}
mSqlCommand = new SqlCommand("OpMngSys.USP_CostumerLogin");
mSqlCommand.Connection = mSqlConnection;
mSqlCommand.CommandType = System.Data.CommandType.StoredProcedure;
mSqlCommand.Parameters.Add("@UserName", SqlDbType.VarChar).Value = pUser.UserName;
mSqlCommand.Parameters.Add("@Password", SqlDbType.VarChar).Value = pUser.Password;
logresult = mSqlCommand.ExecuteNonQuery();
}
return logresult;
}
catch (Exception ex)
{ throw ex; }
}
public int Create(User pUser)
{
return 0;
}
//public int Delete(User pUser)
//{
// return 0;
//}
}
}
ASP.Net頁面:
<%@ Page Title="" Language="C#" MasterPageFile="~/Public/Site.Master" AutoEventWireup="true" CodeBehind="Usuario.aspx.cs" Inherits="Demo_CSP.Usuario" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<meta charset="utf-8" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:ScriptManager ID="ScriptManager2" runat="server" ></asp:ScriptManager>
<asp:TextBox ID="TextUserNameLog" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="UserNameValid" ErrorMessage="Invalid" runat="server" ForeColor="Red" ControlToValidate="TextUserNameLog">*</asp:RequiredFieldValidator>
<asp:TextBox ID="TextPasswordLog" runat="server" TextMode="Password"></asp:TextBox>
<asp:Button ID ="BtnLog" runat="server" Text="Ingresar" OnClick="BtnLog_Click" />
<asp:RequiredFieldValidator ID="PasswordValid" ErrorMessage="Invalid" runat="server" ForeColor="Red" ControlToValidate="TextPasswordLog">*</asp:RequiredFieldValidator>
<asp:Login ID="LogBot" LoginButtonText="Ingresar" runat="server" OnAuthenticate="LogBot_Authenticate"></asp:Login>
</asp:Content>
Usuario.aspx.cs
代碼隱藏:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Configuration;
namespace Demo_CSP
{
public partial class Usuario : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void LogBot_Authenticate(object sender, AuthenticateEventArgs e)
{
Data.Models.User MyUser = new Data.Models.User();
//MyUser.UserName = TextUserNameLog.Text;
//MyUser.Password = TextPasswordLog.Text;
MyUser.UserName = LogBot.UserName;
MyUser.Password = LogBot.Password;
Business.MngUser objuser = new Business.MngUser(ConfigurationManager.AppSettings["SqlCnn"].ToString());
Business.ObjRespuesta resp = objuser.AccountLogin(MyUser);
int Id = 0;
switch (Id)
{
case -1:
LogBot.FailureText = "Error de Usuario/Contraseña";
break;
case -2:
LogBot.FailureText = "No existe Usuario";
break;
default:
string message = "Prueba exitosa";
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("alert('");
sb.Append(message);
sb.Append("');");
ClientScript.RegisterOnSubmitStatement(this.GetType(), "alert", sb.ToString());
break;
}
}
protected void BtnLog_Click(object sender, EventArgs e)
{
Data.Models.User MyUser = new Data.Models.User();
MyUser.UserName = TextUserNameLog.Text;
MyUser.Password = TextPasswordLog.Text;
Business.MngUser objuser = new Business.MngUser(ConfigurationManager.AppSettings["SqlCnn"].ToString());
Business.ObjRespuesta resp = objuser.AccountLogin(MyUser);
//MyUser.UserName = TextUserNameLog.Text;
//MyUser.Password = TextPasswordLog.Text;
}
}
}
這是存儲過程:
IF EXISTS(SELECT 1 FROM sys.objects WHERE name = 'USP_CustomerLogin' AND type = 'P')
BEGIN
DROP PROCEDURE OpMngSys.USP_Customer_NewCustomer
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE OpMngSys.USP_CostumerLogin
@UserName VARCHAR(100),
@Password VARCHAR(150),
@IsExists INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (SELECT UserName, [Password]
FROM [Security].[Users]
WHERE UserName = @UserName and [Password] = @Password)
BEGIN
SET @IsExists = -1
END
ELSE
BEGIN
SET @IsExists = 1
END
RETURN @IsExists
END
GO
我真的很沮喪......我需要對我的模板進行驗證......
我相信你需要在Entrar方法的UserEntity中添加一個輸出參數。
例如:
SqlParameter outputIsExists = new SqlParameter("@IsExists", SqlDbType.Int)
{
Direction = ParameterDirection.Output
};
mSqlCommand.Parameters.Add(outputIsExists);
調用ExecuteNonQuery后,可以從output參數中獲取值。 例如:
mSqlCommand.ExecuteNonQuery();
logresult = (int)outputIsExists.Value;
完整的Entrar方法看起來像這樣:
public int Entrar(User pUser) {
int logresult = 0;
try {
if (CreateConnection())
{
if (mSqlConnection != null && mSqlConnection.State != ConnectionState.Open) {
mSqlConnection.Open();
}
mSqlCommand = new SqlCommand("OpMngSys.USP_CostumerLogin");
mSqlCommand.Connection = mSqlConnection;
mSqlCommand.CommandType = System.Data.CommandType.StoredProcedure;
mSqlCommand.Parameters.Add("@UserName", SqlDbType.VarChar).Value = pUser.UserName;
mSqlCommand.Parameters.Add("@Password", SqlDbType.VarChar).Value = pUser.Password;
SqlParameter outputIsExists = new SqlParameter("@IsExists", SqlDbType.Int) {
Direction = ParameterDirection.Output
};
mSqlCommand.Parameters.Add(outputIsExists);
mSqlCommand.ExecuteNonQuery();
logresult = (int)outputIsExists.Value;
}
return logresult;
}catch (Exception ex)
{
throw ex;
}
}
您需要更改存儲過程以將值作為結果集 (而不是RETURN
語句) RETURN
:
CREATE PROCEDURE OpMngSys.USP_CostumerLogin
@UserName VARCHAR(100),
@Password VARCHAR(150)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @IfExists BIT
IF EXISTS (SELECT UserName, [Password]
FROM [Security].[Users]
WHERE UserName = @UserName and [Password] = @Password)
BEGIN
SET @IfExists = 1
END
ELSE
BEGIN
SET @IfExists = 0
END
SELECT @IfExists -- return as a result set
END
然后你需要更改你的C#代碼以使用ExecuteScalar()
來獲取該值:
mSqlCommand = new SqlCommand("OpMngSys.USP_CostumerLogin", mSqlConnection);
mSqlCommand.CommandType = System.Data.CommandType.StoredProcedure;
mSqlCommand.Parameters.Add("@UserName", SqlDbType.VarChar, 100).Value = pUser.UserName;
mSqlCommand.Parameters.Add("@Password", SqlDbType.VarChar, 150).Value = pUser.Password;
mSqlConnection.Open();
object resultset = mSqlCommand.ExecuteScalar();
mSqlConnection.Close();
bool userDoesExist;
if(resultset != null)
{
if (bool.TryParse(resultset.ToString(), out userDoesExist))
{
return userDoesExist;
}
else
{
// ERROR: cannot convert result to a "bool"
}
}
我看到兩件事。
首先 ,StoredProcedure將為您提供反向結果,這是1(有效)的不正確憑證和-1(無效) 。 這是因為IF-ELSE邏輯不正確。 我會將結果-1改為1,反之亦然。
StoredProcedure的完整Transact-SQL腳本如下:
IF EXISTS(SELECT 1 FROM sys.objects WHERE name = 'USP_CustomerLogin' AND type = 'P')
BEGIN
DROP PROCEDURE OpMngSys.USP_Customer_NewCustomer
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE OpMngSys.USP_CostumerLogin
@UserName VARCHAR(100),
@Password VARCHAR(150),
@IsExists INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (SELECT UserName, [Password]
FROM [Security].[Users]
WHERE UserName = @UserName and [Password] = @Password)
BEGIN
SET @IsExists = 1
END
ELSE
BEGIN
SET @IsExists = -1
END
RETURN @IsExists
END
GO
其次我會說Donal是對的。 您沒有存儲在StoredProcedure上聲明的輸出,這是必要的步驟。
Imho CreateConnection()
函數和UserEntity.cs
中的Dispose()
邏輯不是必需的,因為SqlConnection已經是IDisposable
完整的UserEntity.cs
會如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Data.Interfaces;
using Data.Models;
using System.Data.SqlClient;
using System.Data;
using System.Web;
namespace Data
{
public class UserEntity:IUser, IDisposable
{
private string mSqlCnn;
public UserEntity(string SqlCnn)
{
mSqlCnn = SqlCnn;
}
public void Dispose()
{
mSqlCnn = null;
}
public int Entrar(User pUser)
{
int logresult = 0;
//SqlConnection is IDisposable, and it occupies from closing connection.
using(SqlCOnnection mSqlConnection = new SqlConnection(mSqlCnn))
{
try
{
mSqlConnection.Open();
mSqlCommand = new SqlCommand("OpMngSys.USP_CostumerLogin",mSqlConnection);
mSqlCommand.CommandType = CommandType.StoredProcedure;
//Add Input Parameters
mSqlCommand.Parameters.Add("@UserName", SqlDbType.VarChar).Value = pUser.UserName;
mSqlCommand.Parameters.Add("@Password", SqlDbType.VarChar).Value = pUser.Password;
//Declare output parameter that will receive the result
SqlParameter outputIsExists = new SqlParameter("@IsExists", SqlDbType.Int) {
Direction = ParameterDirection.Output
};
mSqlCommand.Parameters.Add(outputIsExists);
//ExecuteNonQuery won't give any result
mSqlCommand.ExecuteNonQuery();
//Get the value that has been set by the StoredProcedure in the output parameter
logresult = (int)outputIsExists.Value
}
catch (Exception ex)
{ throw ex; }
}
return logresult;
}
public int Create(User pUser)
{
return 0;
}
//public int Delete(User pUser)
//{
// return 0;
//}
}
}
注意:如果您收到錯誤。
“過程或函數USP_CostumerLogin指定了太多參數。”
可能是您的StoredProcedure不接受OUTPUT參數。 換句話說,也許你沒有使用你在這里為StoredProcedure編寫的代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.