ASP MVC中唯一性的远程验证

时间:2017-11-02 15:32:42

标签: c# jquery sql-server asp.net-mvc

使用ASP MVC和SQL Server,我试图通过他的电子邮件价值的独特性来测试客户端的存在。

经过大量的教程和解决方案,我没有成功解决这个问题。这就是我尝试过的:

ClientController:

 [HttpPost]
    public ActionResult Create(Client cmodel)
    {
        try
        {
            if (ModelState.IsValid)
            {
                ClientManagement cdb = new ClientManagement();
                if (cdb.AddClient(cmodel))
                {

                    ViewBag.Message = "Client Details Added Successfully";
                    ModelState.Clear();
                }
            }
            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }

 public JsonResult IsClientExist(string Email)
    {

        List<Client> cm = new List<Client>();

        return Json(!cm.Any(x => x.Email == Email), JsonRequestBehavior.AllowGet);
    }

Class ClientManagement:

 public bool AddClient(Client cmodel)
    {
        connection();
        SqlCommand cmd = new SqlCommand("AddNewClients", con);
        cmd.CommandType = CommandType.StoredProcedure;

        cmd.Parameters.AddWithValue("@Email", cmodel.Email);
        cmd.Parameters.AddWithValue("@Password", cmodel.Password);

        con.Open();
        int i = cmd.ExecuteNonQuery();
        con.Close();

        if (i >= 1)
            return true;
        else
            return false;
    }

模型客户端:

 public class Client
{

    [Display(Name = "Email")]
    [Required(ErrorMessage = "Email is required.")]
    [EmailAddress(ErrorMessage = "Invalid Email Address")]
    [DataType(DataType.EmailAddress)]
    [StringLength(30)]
    [Remote("IsClientExist", "Client", ErrorMessage = "Email is already exists in Database.")]
    public string Email { get; set; }

    [Display(Name = "Password")]
    [DataType(DataType.Password)]
    [Required(ErrorMessage = "Password is required.")]
    public string Password { get; set; }
}

查看制作:

<div class="form-group">
        @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
        </div>
    </div>
    <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    <script src="~/Scripts/jquery.validate.min.js"></script>
   <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

2 个答案:

答案 0 :(得分:2)

您需要在数据库中的电子邮件中添加唯一约束或唯一索引。

即使在插入之前检查是否存在,并发请求也可能导致重复。因此,当您尝试插入重复项时,数据库会强制执行唯一性并处理它返回的错误。

答案 1 :(得分:2)

您当前的代码正在重新检查Client的空列表。您应该检查现有数据。

您可以编写一个方法来检查

private bool DoesEmailExist(string email)
{
    var conStr = @"putYourConnectionStringHere";
    var q = "select TOP 1 Email from Client WHERE Email=@email";

    using (var c =new SqlConnection(conStr))
    {
       using (var cmd = new SqlCommand(q, c))
       {
            c.Open();
            cmd.Parameters.AddWithValue("@email", email);
            var r = cmd.ExecuteReader();
            return r.HasRows;
       }
    }
}

现在,您可以在其他方法中调用此方法。 当电子邮件存在于系统中时,您的IsClientExist应返回false,并且当数据库中不存在时,应返回true 。所以基本上你需要否定从DoesEmailExist方法

返回的结果
public JsonResult IsClientExist(string Email)
{
    var r = DoesEmailExist(Email);
    return Json(!r, JsonRequestBehavior.AllowGet);
}

请记住,这只会进行客户端验证。 永远不要信任来自客户端的数据。始终在服务器端进行验证。您应该添加数据库级别约束,以防止重复的电子邮件保存在表中,如@David Browne在他的回答中所述