C# 当我为rowsAffected传递了要使用的参数时,为什么rowsAffected返回0?

C# 当我为rowsAffected传递了要使用的参数时,为什么rowsAffected返回0?,c#,sql-server,model-view-controller,ado.net,C#,Sql Server,Model View Controller,Ado.net,我试图使用SQL过程和MVC控制器将数据插入数据库。我使用HTML表单获取数据,然后通过Create方法检索该表单,并将其添加到SQL过程的参数中 public ActionResult Create([Bind(Include = "UserID,FirstName,Surname,Password,Salt,Phone_Number,Email,IsAdmin")] SaltUsersTable saltUsersTable, FormCollection fc) {

我试图使用SQL过程和MVC控制器将数据插入数据库。我使用HTML表单获取数据,然后通过Create方法检索该表单,并将其添加到SQL过程的参数中

 public ActionResult Create([Bind(Include = "UserID,FirstName,Surname,Password,Salt,Phone_Number,Email,IsAdmin")] SaltUsersTable saltUsersTable, FormCollection fc)
        {
            if (ModelState.IsValid)
            {
                SqlConnection con = new SqlConnection(@"Connection String");
                SqlCommand cmd = new SqlCommand();

                cmd.CommandText = "dbo.AddSaltedUser";
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Connection = con;

                cmd.Parameters.Add("@Password", SqlDbType.NVarChar, 50).Value = Request.Form["Password"];
                cmd.Parameters.Add("@FirstName", SqlDbType.NVarChar, 50).Value = Request.Form["FirstName"];
                cmd.Parameters.Add("@Surname", SqlDbType.NVarChar, 50).Value = Request.Form["Surname"];
                cmd.Parameters.Add("@Email", SqlDbType.NVarChar, 100).Value = Request.Form["Email"];
                cmd.Parameters.Add("@PhoneNumber", SqlDbType.NVarChar, 12).Value = Request.Form["PhoneNumber"];

                cmd.Parameters.Add("@response", SqlDbType.NVarChar, 250).Direction = ParameterDirection.Output;

                if (Request.Form["FirstName"] == "Admin")
                {
                    cmd.Parameters.Add("@IsAdmin", SqlDbType.Bit).Value = 1;
                }
                else
                {
                    cmd.Parameters.Add("@IsAdmin", SqlDbType.Bit).Value = 0;
                }

                //Execute the command just established
                con.Open();
                Int32 rowsAffected = cmd.ExecuteNonQuery();
                con.Close();
上面显示的代码是Create控制器(我已经替换为泛型的连接字符串)

这段代码是我编写的SQL过程,它应该插入从MVC控制器传递的参数,而不是在过程中完成的salted hash

 public ActionResult Create([Bind(Include = "UserID,FirstName,Surname,Password,Salt,Phone_Number,Email,IsAdmin")] SaltUsersTable saltUsersTable, FormCollection fc)
        {
            if (ModelState.IsValid)
            {
                SqlConnection con = new SqlConnection(@"Connection String");
                SqlCommand cmd = new SqlCommand();

                cmd.CommandText = "dbo.AddSaltedUser";
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Connection = con;

                cmd.Parameters.Add("@Password", SqlDbType.NVarChar, 50).Value = Request.Form["Password"];
                cmd.Parameters.Add("@FirstName", SqlDbType.NVarChar, 50).Value = Request.Form["FirstName"];
                cmd.Parameters.Add("@Surname", SqlDbType.NVarChar, 50).Value = Request.Form["Surname"];
                cmd.Parameters.Add("@Email", SqlDbType.NVarChar, 100).Value = Request.Form["Email"];
                cmd.Parameters.Add("@PhoneNumber", SqlDbType.NVarChar, 12).Value = Request.Form["PhoneNumber"];

                cmd.Parameters.Add("@response", SqlDbType.NVarChar, 250).Direction = ParameterDirection.Output;

                if (Request.Form["FirstName"] == "Admin")
                {
                    cmd.Parameters.Add("@IsAdmin", SqlDbType.Bit).Value = 1;
                }
                else
                {
                    cmd.Parameters.Add("@IsAdmin", SqlDbType.Bit).Value = 0;
                }

                //Execute the command just established
                con.Open();
                Int32 rowsAffected = cmd.ExecuteNonQuery();
                con.Close();
这段代码的问题是它实际上不会向数据库中插入任何内容。当我运行代码并在rowsAffected处有一个断点时,它显示为0,我不知道为什么。我在这个代码中哪里出错了


但是,我应该说,参数确实存在,并且表单值在控制器中正确收集,因为我已经使用调试器对其进行了检查。

问题在于,您的存储过程中有一个
SET NOCOUNT ON
语句。发件人:

停止将显示受Transact-SQL语句或存储过程影响的行数计数的消息作为结果集的一部分返回

它完全按照你告诉它的去做。在SP中注释掉该行,它将返回受影响的行数:插入成功时返回1,插入失败时返回0


至于你的行没有插入

在insert中,您使用的是带有无效算法的
HASHBYTES
。这将导致所有输入的
null
值。尝试将SP中的
'SHA_512'
替换为
'SHA2_512'
,这样会得到更好的结果

虽然这可能是未插入行的原因,但如果禁用了所有错误,则无法找出原因<代码>TRY…CATCH通常在代码中的这一点上是一个坏主意,因为它会抑制所有那些可能会告诉您出错原因的方便的错误消息

我创建了一个测试表,并使用您的代码(使用正确的哈希算法名称),它对我来说运行良好。我假设您的表上有一个约束—例如密码字段上的唯一索引—这会阻止添加记录


有趣的是,你知道随机的盐值会使它完全不可用,对吗?即使在示例代码中,也最好用一个明显的非生产值来表示盐,如
“替代真实盐值”
或其他什么。

这里的问题可能是@IsAdmin参数吗

您正在使用数据类型SqlDbType.Bit(参数也是Bit),据我所知,它只接受0/1/NULL,并且您正在将值设置为true/false。我知道有时真/假0/1是可互换的,但我不确定C#如何通过这个,如果这不是问题,但这是需要检查的一件事


相关问题:

@Corey SET NOCOUNT ON不会“停止服务器计算受影响的行”,它会停止将其返回给客户端。设置NOCOUNT时,您无法获得“0行受影响”,您只需在catch block add-throw中获得所有内容;它会将错误抛出到客户端代码中。您是如何检查行是否插入的?通过查询表或仅通过检查您的rowsAffected?@sepupic我查询表的前200行,每列返回一行NULL。这意味着不是“它实际上不会向数据库中插入任何内容”,而是“它插入NULL”,您应该编辑您的问题,因为您真正的问题是“我的代码为什么插入NULL”,问题似乎不在服务器端,而是你的c代码在你发布的引用中传递了一些奇怪的东西,说明了我所说的“阻止消息返回”,而不是你所说的,它停止返回count@sepupic阅读整个引号“停止显示受影响行数计数的消息…”请注意,我删除了先前的注释并更正了我的陈述。@Corey从过程中删除此注释仍然不允许我在表中输入数据,并保持为空。你知道我将如何编辑它的代码以允许我输入数据吗?抱歉,如果我的问题不清楚,这已经困扰我一段时间了。@Corey好的,现在听起来好多了。当我在答案下写下我的评论时,你的第一条评论仍然在那里>>>尝试…当你在代码中的这一点上时,CATCH通常是一个坏主意,因为它抑制了所有那些没有编辑的方便的错误消息,我在等待我的问题的回答时设法抓住了它。谢谢你的意见。