C#中的SQLCommand不提供参数

C#中的SQLCommand不提供参数,c#,json,asp.net-web-api,C#,Json,Asp.net Web Api,我在c#中有一个函数,就是插入数据。它所要做的就是调用一个由我通过Fiddler提供的请求体给出的存储过程。现在我正在尝试测试它,但我一直得到这个错误 过程或函数“spCreatePerson”需要参数“@first”,但未提供该参数 这是目标- public class Person { public int Id { get; set; } public string FirstName { get; set; } public string LastName { g

我在c#中有一个函数,就是插入数据。它所要做的就是调用一个由我通过Fiddler提供的请求体给出的存储过程。现在我正在尝试测试它,但我一直得到这个错误

过程或函数“spCreatePerson”需要参数“@first”,但未提供该参数

这是目标-

public class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string Phone { get; set; }

    public string Email { get; set; }

    public int PersonTypeId { get; set; }
}
这是请求主体-

{"FirstName":"Test","LastName":"MuhFuh","Phone":"5555555555","Email":"test@gmail.com","PersonTypeId":1}
下面是调用proc的函数-

public static int InsertData(string procName, Person p)
    {
        int rowsAffected = 0;

        con = CreateConnection();

        using (con)
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd = new SqlCommand("spCreatePerson", con);

            cmd.Parameters.AddWithValue("@first", p.FirstName);
            cmd.Parameters.AddWithValue("@last", p.LastName);
            cmd.Parameters.AddWithValue("@email", p.Email);
            cmd.Parameters.AddWithValue("@phone", p.Phone);
            cmd.Parameters.AddWithValue("@pTypeID", p.PersonTypeId);

            rowsAffected = cmd.ExecuteNonQuery();
        }

        return rowsAffected;
    }
正如您所看到的,我传入了参数,但得到了这个错误。密码里有我遗漏的东西吗?我走了过去,数据似乎传递得很好

编辑

这是存储过程-

CREATE PROC [dbo].[spCreatePerson] @first nvarchar(100), @last 
nvarchar(100), @email nvarchar(50), @phone nvarchar(100), @pTypeID int

AS

INSERT INTO Person(FirstName, LastName, Email, Phone, PersonTypeID)
VALUES(@first, @last, @email, @phone, @pTypeID)


GO
这可能是罪魁祸首,但至少这是整个方程中要消除的一个变量。这些线路非常可疑:

cmd.CommandType = CommandType.StoredProcedure;
cmd = new SqlCommand("spCreatePerson", con);
一方面,第二行完全否定了第一行。它们应该交换:

cmd = new SqlCommand("spCreatePerson", con);
cmd.CommandType = CommandType.StoredProcedure;
但更重要的是,它们说明了一个更大的潜在问题。即

cmd
con
在哪里声明和创建

如果您使用的是存在于更大范围内的连接和命令对象,则可能与其他操作共享它们。这是一件坏事,可能会导致很难诊断错误

根据一般经验,应该在尽可能小的范围内声明、创建、使用和处置命令和连接。

保持它们的存在不会带来任何好处,底层系统已经得到了很好的优化。但是您正在做的是打开代码中出现bug和奇怪行为的可能性

结构基本上应该是(在某种程度上是伪代码):


调试时,
p.FirstName
是否包含值?@David yes。“Test”正从请求主体中顺利传入。我对它进行了调试,所有的数据似乎都在进行中。你能在这里的问题中添加存储的proc脚本吗?一件奇怪的事情是,你正在设置cmd.CommandType=CommandType.StoredProcedure;在创建SqlCommand之前。之后,您将重新创建此对象,这是一个潜在的问题。永远不要使用全局SqlCommand。最好编写var cmd=newsqlcommadn(“stuff”,con);cmd.CommandType=CommandType.storedProcess@KrazyDev停止使用全局变量这是一种糟糕的做法。这将有助于您将来避免此类问题。它们是我的DBHelper类中的全局变量。@KrazyDev:一个具有讽刺意味的名称的类:)看到此方法也是静态的,这是另一个潜在问题。您可能想看看类似于存储库模式的东西(使用实体框架实现它很简单)。或者至少是充当存储库的服务类。基本上,坚持使用面向对象的代码。“全局”的东西和“使所有东西都静止”是通往错误代码的黑暗世界的一个滑坡。
using (var con = new Connection())
using (var cmd = new Command(con))
    // set parameters, command type, etc.
    // execute the command, get any results you might need
}
// any follow-up logic, etc.