0

我有一个网络表单,我需要在其中使用唯一 ID 添加、更新、删除和读取。到目前为止,我已经设法轻松地添加、更新和删除功能。

但是现在我无法让我的读取功能正常工作(了解我有一个包含四个文本字段的网络表单;ID、FIRSTNAME、SURNAME 和 ADDRESS)。基本上,当先前创建的 ID(使用添加按钮)输入到文本字段并单击读取按钮时,它应该根据输入的 ID 使用存储的条目更新其他 3 个文本字段。

这是我在网络表单上的背后代码(cs.)

protected void cmdRead_Click(object sender, EventArgs e)
{
   // Create a reference to the Web service
   DbWebService.WebService1 proxy = new DbWebService.WebService1();

   // Create a person details object to send to the Web service.
   string ADDRESS;
   string SURNAME;
   string FIRSTNAME;
   string ID;

   ADDRESS = txtAddress.Text;
   SURNAME = txtSurname.Text;
   FIRSTNAME = txtFirstname.Text;
   ID = txtID.Text;

   // Attempt to store in the Web service
   bool rsp = proxy.ReadPerson(int.Parse(ID), FIRSTNAME, SURNAME, ADDRESS);

   // Inform the user
   if (rsp)
   {
       lblOutcome.Text = "Successfully read data.";

       txtFirstname.Text = FIRSTNAME;
       txtSurname.Text = SURNAME;
       txtAddress.Text = ADDRESS;
   }
   else
   {
       lblOutcome.Text = "Failed to read data! Select a previously created ID!";
   }
}

这是我在网络服务上的网络功能(这是 SQL Server Express 数据库所在的位置)

[WebMethod]
public bool ReadPerson(int ID, string FIRSTNAME, string SURNAME, string ADDRESS)
{
   // In case of failure failure first
   bool rtn = false;

   // Connect to the Database
   SqlConnection connection = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename='|DataDirectory|\Database.mdf';Integrated Security=True;User Instance=True");

   // Open the connection
   connection.Open();

   // Prepare an SQL Command
   SqlCommand command = new SqlCommand(String.Format("SELECT FIRSTNAME, SURNAME, ADDRESS FROM PersonalDetails WHERE ID = '{0}'", ID), connection);

   // Execute the SQL command and get a data reader.
   SqlDataReader reader = command.ExecuteReader();

   // Instruct the reader to read the first record.
   if (reader.Read())
   {
      // A record exists, thus the return value is updated
      FIRSTNAME = (string)reader["FIRSTNAME"];
      SURNAME = (string)reader["SURNAME"];
      ADDRESS = (string)reader["ADDRESS"];

      rtn = true;
   }

   // Close the connection
   connection.Close();

   // Return the result.
   return (rtn);

}

现在的问题是,当我单击读取时,我收到一条成功消息(使用您在后面的代码中看到的标签)但字段没有更新,我认为这是因为 ( rtn = true;) 语句。因此,我认为这样的事情可能会奏效:

rtn = (bool)reader["ADDRESS"];

但是,有了这个,我得到一个指定的强制转换无效,所以我认为 bool 在这种情况下可能不起作用,我认为如果我使用字符串而不是它可能会起作用,但是我如何转换,我认为 rtn 需要一个值给读者吧??

基本上,我只是在寻找一种可以更新 Web 表单中的文本字段的解决方案。

4

1 回答 1

1

您的代码有几个问题。最明显的是您的代码永远无法从数据库中返回数据。您正在将FIRSTNAME等发送Web 服务 - 您没有Web 服务返回它们。

没有理由让bool服务返回来告诉您它是否成功。如果服务失败,让服务抛出异常。相反,您应该从数据库中返回字段作为服务的返回。

在服务中:

public class Person
{
    public string FIRSTNAME {get;set;}
    public string SURNAME {get;set;}
    public string ADDRESS {get;set;}
}

[WebMethod]        
public Person ReadPerson(int ID)        
{        
    // ...
    if (reader.Read()) 
    { 
        // A record exists, thus return the value
        Person p = new Person();
        p.FIRSTNAME = (string)reader["FIRSTNAME"]; 
        p.SURNAME = (string)reader["SURNAME"]; 
        p.ADDRESS = (string)reader["ADDRESS"]; 

        rtn = p;
   } 

    connection.Close();          

    return rtn; 
}           

此外,除非别无选择,否则不应使用 WebMethod 或 ASMX Web 服务。ASMX 是一种遗留技术,仅用于向后兼容。它不应该用于新的开发。您应该改用 WCF。


您的代码的其他问题在下面得到解决:

[WebMethod]
public Person ReadPerson(int id)
{
    using (
        var connection =
            new SqlConnection(
                @"Data Source=.\SQLEXPRESS;
        AttachDbFilename='|DataDirectory|\Database.mdf';
        Integrated Security=True;
        User Instance=True")
        )
    {
        connection.Open();

        using (
            var command =
                new SqlCommand(@"
SELECT FIRSTNAME, SURNAME, ADDRESS 
FROM PersonalDetails 
WHERE ID = @id",
                    connection))
        {
            var idParameter =
                command.Parameters.Add(
                    "@id", SqlDbType.Int);
            idParameter.Value = id;

            using (var reader = command.ExecuteReader())
            {
                if (!reader.Read())
                {
                    return null;
                }

                return new Person
                            {
                                Firstname =
                                    (string)
                                    reader["FIRSTNAME"],
                                Surname =
                                    (string)
                                    reader["SURNAME"],
                                Address =
                                    (string)
                                    reader["ADDRESS"]
                            };
            }
        }
    }
}

主要问题是SqlConnection,SqlCommandSqlDataReaderall 需要在using块内实例化。这确保无论是否抛出异常,对象都被处理(关闭)。

其次,你不应该养成通过字符串操作来构建查询的习惯;甚至不使用 String.Format。这使您容易受到“SQL 注入”攻击。使用参数可以解决这个问题。请参阅 MSDN 中的“命令和参数”。

最后一个小问题:我建议你改掉对明显陈述发表评论的习惯。例如,不需要注释Open打开与数据库的连接或return返回值。

于 2012-04-29T03:42:52.880 回答