簡體   English   中英

ASP.NET用戶驗證

[英]ASP.NET User Validation

我在代碼中感到困惑,我需要使用ASP.Net和存儲過程驗證UserNamePassword ,但是所有時間我都得到-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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM