使用SQL Server存储过程实现用户认证后页面跳转失效问题排查
核心问题与修复要点
致命错误:提前触发跳转
按钮点击事件第一行的Server.Transfer("NadzornaPloca1.aspx")会直接终止当前页面逻辑,跳转到目标页面,导致后续的用户认证代码完全不会执行。必须删除这行代码。错误封装Response对象
ASP.NET Page类自带原生Response属性,不需要自定义_Response、GetResponse()这类方法。自定义的_Response如果未正确赋值,调用Redirect时会触发空引用异常,直接用Response.Redirect()即可。控件类型定义错误
TextBoxUserName和TextBoxPassword被定义为Object类型,应改为TextBox类型,否则访问.Text属性可能引发运行时错误(Object类型没有Text属性)。同时建议用Protected修饰,确保ASPX页面能正常访问控件。误用WinForm弹窗API
ASP.NET Web环境不能使用MessageBox.Show()(这是Windows窗体的API),需改用客户端JavaScript弹窗,比如通过ClientScript.RegisterStartupScript输出alert提示。跳转逻辑依赖未验证的输入
认证成功后直接用用户输入的用户名判断跳转,存在安全风险(用户可能篡改输入)。应该使用存储过程返回的@ValidUser输出值来判断,确保是经过认证的合法用户名。硬编码连接字符串
连接字符串硬编码在代码中不利于维护,建议移到Web.config的<connectionStrings>节点中。空异常处理
Catch块为空无法排查问题,应添加错误提示或日志记录。
修复后的完整代码
Imports System.Data.SqlClient Imports System.Configuration Public Class LoginPage Inherits System.Web.UI.Page ' 从Web.config读取连接字符串 Private ReadOnly connectionString As String = ConfigurationManager.ConnectionStrings("VodeneProjektaConn").ConnectionString ' 修正控件类型为TextBox,使用Protected让ASPX页面可访问 Private WithEvents ButtonLogin As Button Protected WithEvents TextBoxUserName As TextBox Protected WithEvents TextBoxPassword As TextBox Private Sub ButtonLogin_Click(sender As Object, e As EventArgs) Handles ButtonLogin.Click Dim params(2) As SqlParameter params(0) = New SqlParameter("@Korisničko_ime", SqlDbType.NVarChar, 50) params(0).Value = TextBoxUserName.Text.Trim() params(1) = New SqlParameter("@Zaporka", SqlDbType.NVarChar, 50) params(1).Value = TextBoxPassword.Text.Trim() params(2) = New SqlParameter("@ValidUser", SqlDbType.NVarChar, 50) params(2).Direction = ParameterDirection.Output ' 使用Using自动释放数据库连接和命令对象 Using connection As New SqlConnection(connectionString) Using command As New SqlCommand("dbo.AuthentifikacijaKorisnika", connection) command.CommandType = CommandType.StoredProcedure command.Parameters.AddRange(params) Try connection.Open() command.ExecuteNonQuery() ' 处理存储过程返回的空值 Dim validUserName As String = If(command.Parameters("@ValidUser").Value Is DBNull.Value, "", command.Parameters("@ValidUser").Value.ToString().Trim()) If Not String.IsNullOrEmpty(validUserName) Then ' 基于认证后的用户名跳转 Select Case validUserName.ToLower() Case "ivan.ivic" Response.Redirect("NadzornaPloca1.aspx", False) Case "ana.anic", "marko.markovic" Response.Redirect("NadzornaPloca2.aspx", False) Case "jasna.jasnic", "igor.igorek", "petra.petrovic", "stjepan.stjepanic", "katarina.katarinovic", "josip.josipovic", "martina.martinovic" Response.Redirect("NadzornaPloca3.aspx", False) Case Else ShowClientMessage("Netočno korisničko ime.") End Select Else ShowClientMessage("Netočno korisničko ime ili lozinka.") End If Catch ex As Exception ' 可添加日志记录,这里先返回错误提示 ShowClientMessage("Došlo je do greške prilikom prijave: " & ex.Message) End Try End Using End Using End Sub ' 封装客户端弹窗方法,处理单引号转义 Private Sub ShowClientMessage(message As String) Dim safeMessage As String = message.Replace("'", "\'") Dim script As String = $"alert('{safeMessage}');" ClientScript.RegisterStartupScript(Me.GetType(), "LoginError", script, True) End Sub End Class
Web.config连接字符串配置示例
<configuration> <connectionStrings> <add name="VodeneProjektaConn" connectionString="Server=PCOFTOMI\SQLEXPRESS;Database=VodeneProjekta;Integrated Security=true" providerName="System.Data.SqlClient" /> </connectionStrings> </configuration>
内容的提问来源于stack exchange,提问作者Tomislav Abicic

