防止重复的电子邮件地址提交c#

时间:2016-10-26 23:45:48

标签: c# asp.net

我在下面有以下c#代码,我试图包含其他功能,以防止使用asp.net表单将重复的电子邮件地址输入数据库。下面是代码,目前它将所有条目,无论是否重复插入数据库。

using System.Data.OleDb;
using System.Configuration;

public partial class Default2 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        OleDbConnection con = new OleDbConnection();
        con.ConnectionString = ConfigurationManager.ConnectionStrings["northwind"].ToString();
        con.Open();
        string query = "SELECT COUNT(ID) FROM Table1 WHERE pEmail=' " + TextBox2.Text + "'";
    OleDbCommand cmd = new OleDbCommand(query, con);
    int count = (int)cmd.ExecuteScalar();

    if (count > 0)
        {
            Label1.Text = "email is already in use";
        }
        else {
        cmd.CommandText = "insert into[Table1](pName, pEmail)values(@nm,@em)";
        cmd.Parameters.AddWithValue("@nm", TextBox1.Text);
        cmd.Parameters.AddWithValue("@em", TextBox2.Text);
        cmd.Connection = con;
        int a = cmd.ExecuteNonQuery();
        if (a>0)
            {
                Label1.Text = "Inserted Sucessfully!";
            }
        }
    }
}

Asp.net表单代码

<form id="form1" runat="server">
<div style="height: 138px">

    Enter Name:<asp:TextBox ID="TextBox1" runat="server" style="margin-left: 12px"></asp:TextBox>

    <asp:RequiredFieldValidator 
id="reqName" 
ControlToValidate="TextBox1"
Style="color:Red"   
ErrorMessage="Please enter your name!"
runat="server"  />

    <br />
    Enter Email:&nbsp;&nbsp;&nbsp;
    <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>

    <asp:RegularExpressionValidator 
id="ValidEmail" 
ControlToValidate="TextBox2" 
Style="color:Red"
ValidationExpression="^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"
ErrorMessage="Invalid Email Entry" 
runat="server" />

    <br />
    <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Submit" />
    <br />
    <asp:Label ID="Label1" runat="server"></asp:Label>

</div>
</form>

4 个答案:

答案 0 :(得分:1)

我认为这可能是您实例化命令对象的方式,但我没有设置测试项目进行确认的地方。我认为你实际上想要ExecuteReader方法,或者至少我过去常常使用SELECT这样的方法。

这就是我所依据的:OleDbCommand.ExecuteReader

你可以试试像

这样的东西
protected void Button1_Click(object sender, EventArgs e) {
 OleDbConnection con = new OleDbConnection();
 con.ConnectionString = ConfigurationManager.ConnectionStrings["NorthwindConnectionString2"].ToString();
 con.Open();
 string query = "SELECT COUNT(ID) FROM Table1 WHERE pEmail= " + TextBox2.Text;
 OleDbCommand cmd = new OleDbCommand(query, con);
 OleDbDataReader reader = command.ExecuteReader();

 int count = 0;

 while (reader.Read()) {
  count = Convert.ToInt32(reader[0].ToString());
 }
 reader.Close();

 if (count > 0) {
  Label1.Text = "email is already in use";
 } else {
  //re-instantiate the command obj
  cmd = new OleDbCommand();  //empty constructor should work, I think
  cmd.CommandText = "insert into[Table1](pName)values(@nm)";
  cmd.Parameters.AddWithValue("@nm", TextBox1.Text);
  cmd.CommandText = "insert into[Table1](pEmail)values(@nm)";
  cmd.Parameters.AddWithValue("@nm", TextBox2.Text);
  cmd.Connection = con;
  int a = cmd.ExecuteNonQuery();
  if (a > 0) {
   Label1.Text = "Inserted Sucessfully!";
  }
 }
}

答案 1 :(得分:1)

当您正在执行SELECT语句时,您需要OleDbCommand上的ExecuteScalar方法才能获得结果。根据MSDN文档,ExecuteScalar返回:

  

结果集中第一行的第一列,或null   如果结果集为空,则引用。

在您的情况下,返回值将是您查询中COUNT(ID)的值。

ExecuteNonQuery用于修改数据的操作,并返回受查询影响的行数。根据MSDN文档:

  

您可以使用ExecuteNonQuery执行目录操作   例如,查询数据库的结构或创建数据库   诸如表之类的对象,或者在没有的情况下更改数据库中的数据   通过执行UPDATE,INSERT或DELETE语句来使用DataSet。   虽然ExecuteNonQuery不返回任何行,但任何输出参数或   映射到参数的返回值将填充数据。对于   UPDATE,INSERT和DELETE语句,返回值是数字   受命令影响的行数。对于所有其他类型的陈述,   返回值为-1。如果发生回滚,则返回值也是   -1

所以改变你的代码如下:

string query = "SELECT COUNT(ID) FROM Table1 WHERE pEmail='" + TextBox2.Text + "'"; // note: vulnerable to SQLInjection.
OleDbCommand cmd = new OleDbCommand(query, conn);
int count = (int)cmd.ExecuteScalar();

if (count > 0)
{
  // etc.

更新:我还建议您在操作中使用Transaction,以确保在检查重复项和执行实际插入操作之间未添加重复的电子邮件地址。

更新2: 根据切换到使用ExecuteScalar的更新代码,此行:

string query = "SELECT COUNT(ID) FROM Table1 WHERE pEmail=' " + TextBox2.Text + "'";

应该是:

string query = "SELECT COUNT(ID) FROM Table1 WHERE pEmail='" + TextBox2.Text + "'";

(已移除pEmail='"之间的额外空白字符。

答案 2 :(得分:0)

您正在尝试检查电子邮件是否存在这些行:

string query = "SELECT COUNT(ID) FROM Table1 WHERE pEmail= @TextBox2";
int count = cmd.ExecuteNonQuery(query);

但是你没有使用ExecuteNonQuery从数据库中获取数据,你使用的是ExecuteReader。

希望这可以帮助您解决问题。

答案 3 :(得分:0)

ExecuteNonQuery 不接受参数。试试这个:

string query = "SELECT COUNT(ID) FROM Table1 WHERE pEmail= " + TextBox2.Text;

此外,您正在尝试检查 ExecuteNonQuery 的返回值,该值实际返回受影响的行数。但这不是您的SQL语句返回的值。如果您想获得SQL语句返回的值,则应使用 ExecuteReader ExecuteScalar

我不确定你的查询是否正确。不应该是这样的:

{{1}}