用户代码未处理 SQL 异常

本文关键字:异常 SQL 未处理 代码 用户 | 更新日期: 2023-09-27 18:36:31

网站能够运行,但是当我尝试登录该网站时,我收到此错误:

用户代码未处理 SQL 异常

在这一行=>

catch (SqlException e)
{
    throw e;
}

以下是我用于登录DBmanager的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections;
using System.Data.SqlClient;
using System.Configuration;
namespace TopJobAgencyApp.Class
{
    public class DBManager
    {
        public static int InsertLogin(Registration u)
        {
            int rowsinserted = 0;
            SqlConnection conn = null;
            try
            {
                conn = new SqlConnection();
                conn.ConnectionString = ConfigurationManager.ConnectionStrings["TopJobdb"].ConnectionString;
                conn.Open();
                SqlCommand comm = new SqlCommand();
                comm.Connection = conn;
                comm.CommandText = "INSERT INTO topJobUser(username, email, password)" +
                                   " VALUES (@username, @email, @password)";
                comm.Parameters.AddWithValue("@username", u.UserName);
                comm.Parameters.AddWithValue("@email", u.Email);
                comm.Parameters.AddWithValue("@password", u.Password);
                rowsinserted = comm.ExecuteNonQuery();
            }
            catch (SqlException e)
            {
                throw e;
            }
            return rowsinserted;
        }
    }
}

下图是错误消息在此处输入图像描述

用户代码未处理 SQL 异常

例外相当明显:

用户

"用户"登录失败。

这意味着与连接字符串关联的用户没有相关 SQL Server 的登录权限。

可能的解决方案

  1. 验证用户是否具有 SQL Server 的登录权限,然后验证连接字符串中的凭据。

  2. 如果在 IIS 下使用 Windows 身份验证,则需要将身份验证模式设置为 Windows(请参阅下面的示例)。

  3. 如果使用实体框架(基于示例代码,则不是),则可能需要从连接字符串中删除Integrated Security=True;并且可能还需要从连接字符串中删除User Instance=True

Windows 身份验证模式的示例 web.config:

<system.web>
    <authentication mode="Windows"/>
</system.web>

让我们聊聊一下发布的代码...

返回类型

public static int InsertLogin(Registration u)

返回 int 的目的是什么?使用 ExecuteNonQuery 时,结果是受影响的行总数,其中可能包括受插入触发器影响的行。在大多数情况下,insert 方法应返回新插入的行的标识或插入的实际新实体。

处理连接

conn = new SqlConnection();

SqlConnection(与 SqlCommand 一样)实现了 IDisposible,因此您希望使用 using 语句轻松关闭/处置连接。

尝试/捕获

try
{
    // sql
}
catch (SqlException e)
{
    throw e;
}    

在没有任何异常处理的情况下接住然后扔的钱包是什么? 即日志记录、重试等...无论如何,如果确实需要重新抛出异常,则只需使用 throw ;通过使用throw e将丢失堆栈跟踪。

添加参数

comm.Parameters.AddWithValue("@username", u.UserName);

尽管 AddWithValue 有效,但更好的做法是添加具有定义类型的参数。请参阅我们可以停止使用 AddWithValue() 吗?了解更多信息。

重构

现在我们了解了一些背景,可以清理该方法:

// not ideal, but let's hold the connection string in a backing field
// would be better if the connection string could be passed in at runtime
// instead of the data access layer needing direct access to the config file
private static readonly string ConnString = ConfigurationManager.ConnectionStrings["TopJobdb"].ConnectionString;
public static void InsertLogin(Registration u)
{
    using (var conn = new SqlConnection(ConnString))
    using (var cmd = new SqlCommand()
    {
        cmd.Connection = conn;
        cmd.CommandText = "INSERT INTO topJobUser(username, email, password) VALUES (@username, @email, @password)";
        // be sure to set the size value correctly
        cmd.Parameters.Add("@username", SqlDbType.VarChar, 100).Value = u.UserName;
        cmd.Parameters.Add("@email", SqlDbType.VarChar, 100).Value = u.Email;
        cmd.Parameters.Add("@password", SqlDbType.VarChar, 100).Value = u.password;
        conn.Open();
        cmd.ExecuteNonQuery();
    }
}

笔记:

  • 没有尝试/捕获,因为没有要恢复的内容,并且没有管理其他异常处理。
  • 该方法返回 void,因为返回的行数不向使用者提供任何信息。
  • 如果要返回插入行的标识,有几个示例可以搜索。

首先,如果要处理异常,则不应"抛出"错误。异常处理的想法是"处理"异常,而不是使应用程序崩溃。

您在这里所做的是捕获异常并将其扔回去。

应修改代码以显示友好的错误消息,并调查异常消息和可能存在的任何其他内部异常。

您创建的异常对象 e。您会发现许多有用的信息存储在其属性中。您应该探索源,消息,内部异常..等。

其次,从您的错误消息来看,登录凭据似乎是错误的。确保您的用户名和密码正确无误。此外,请检查连接字符串是否按顺序排列。

您还可以设置断点并在执行期间检查代码。