c# - 如何使用 C# 从 SQL Server 获取参数输出并将值放入会话变量中
问题描述
我正在尝试从 SQL Server 中的选择中获取用户角色,以根据会话值阻止某些页面。但实际上我获得了一个空值。为了获得角色,我有一个带有输出参数的存储过程。
CREATE PROCEDURE obtenerROl
@user varchar(20),
@passwrd varchar(20),
@rol tinyint OUTPUT
AS
BEGIN
SELECT @rol = idROl
FROM Users
WHERE nameUSer = @user AND password = @passwrd
RETURN @rol
END
在login.aspx.cs
页面中,我尝试检索输出参数的值并放入会话变量中。
public void obtenerRol()
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["connDb"].ConnectionString))
{
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "obtenerROl";
cmd.Parameters.Add("@user", SqlDbType.VarChar).Value = txtUsuario.Text.Trim();
cmd.Parameters.Add("@passwrd ", SqlDbType.VarChar).Value = txtContraseña.Text.Trim();
SqlParameter rol = new SqlParameter("@rol", SqlDbType.TinyInt);
rol.Direction = ParameterDirection.Output;
cmd.Parameters.Add(rol);
cmd.Connection = conn;
cmd.ExecuteReader(CommandBehavior.CloseConnection);
conn.Open();
Session["UserRole"] = cmd.Parameters["@rol"].Value.ToString();
}
}
登录后,在主页中我有一个标签,仅用于检查会话的值。
mensajeID.Text = Session["UserRole"].ToString();
但我在那条线上遇到了错误:
System.Web.SessionState.HttpSessionState.this[string].get 返回 null。
所以我猜这个方法效果不好。
我添加的最后一行是
cmd.ExecuteReader(CommandBehavior.CloseConnection);
因为我读到有必要关闭数据读取器来处理输出参数,但它没有用。我希望你能帮助我解决我的问题,问候。
解决方案
嗨,我只能在这里发布代码,这就是我编写它的方式(无法测试):
我假设您的默认数据库架构是dbo
=> dbo.obtenerROl
。
public void obtenerRol()
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["connDb"].ConnectionString))
using (SqlCommand cmd = new SqlCommand("dbo.obtenerROl", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@user", SqlDbType.VarChar).Value = txtUsuario.Text.Trim();
cmd.Parameters.Add("@passwrd ", SqlDbType.VarChar).Value = txtContraseña.Text.Trim();
SqlParameter rol = new SqlParameter("@rol", SqlDbType.TinyInt);
rol.Direction = ParameterDirection.Output;
cmd.Parameters.Add(rol);
conn.Open();
cmd.ExecuteNonQuery();
//according to https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/linq/sql-clr-type-mapping
byte userRole = (byte) cmd.Parameters["@rol"].Value;
Session["UserRole"] = userRole;
conn.Close();
}
}
和
CREATE PROCEDURE obtenerROl
@user varchar(20),
@passwrd varchar(20),
@rol tinyint OUTPUT
AS
BEGIN
SELECT @rol = idROl
FROM Users
WHERE nameUSer = @user AND password = @passwrd
RETURN 0; -- for success
END
你也可以
CREATE PROCEDURE obtenerROl
@user varchar(20),
@passwrd varchar(20)
AS
BEGIN
DECLARE @rol tinyint = 0; -- default role
SELECT @rol = idROl
FROM Users
WHERE nameUSer = @user AND password = @passwrd;
SELECT @rol;
END
和您的 C# 代码:
ExecuteScalar 将获得@rol。
public void obtenerRol()
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["connDb"].ConnectionString))
using (SqlCommand cmd = new SqlCommand("dbo.obtenerROl", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@user", SqlDbType.VarChar).Value = txtUsuario.Text.Trim();
cmd.Parameters.Add("@passwrd ", SqlDbType.VarChar).Value = txtContraseña.Text.Trim();
conn.Open();
var value = cmd.ExecuteScalar();
//according to https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/linq/sql-clr-type-mapping
byte userRole = (byte)value;
Session["UserRole"] = userRole;
conn.Close();
}
}
要完整:
- 清理用户输入(txtUsuario/txtContrasena - 可能是 TextInputFields?)以防止 SQL 注入MSDN:SQL 注入
- 永远不要在数据库中保存密码明文SO:用户数据的一些最佳实践
推荐阅读
- go - 使用反射确定类型是否为字符串
- node.js - 无法运行“npm run watch”,错误消息引发“gulp”错误
- python - 两个字符串之间的相关性
- python - Xoring 字符串并仅返回十六进制
- gcc - Rstudio 中存储的 gcc 库链接在哪里?我需要改变它
- centos - 如何避免 centos-release rpm 通过 spacewalk 安装 yum repo 文件
- reactjs - 如何在链接“to”属性中传递回调函数
- python - “是否有基于数据框另一列的某些值添加新列的 pandas 函数?”
- docker - docker: 'build' 不是 docker 命令
- sql - SQL查询中断发生时间和持续时间