【问题标题】:Remote Validation of Uniqueness in ASP MVCASP MVC 中唯一性的远程验证
【发布时间】:2017-11-02 15:32:42
【问题描述】:

使用 ASP MVC 和 SQL Server,我试图在通过其电子邮件值的唯一性创建客户端之前测试客户端的存在。

按照很多教程和解决方案,我没有成功解决这个问题。这是我尝试过的:

客户端控制器:

 [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);
    }

类 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>

【问题讨论】:

  • IsClientExist 的命名给我带来了问题。如果客户端存在,会因为Any()语句前面的感叹号而返回false。您还会看到一个空列表中是否有任何内容,这将始终为 false,因此该方法将始终返回 true。
  • 你为什么不检查用户是否存在并且他们不添加......如果他们更新......
  • 不仅如此。你否定你的结果。因此,如果该列表中确实存在客户端,您的 IsClientExist 方法将返回 false。因此,在我看来,您需要将数据加载到该列表中,并删除 Any() 语句之前的感叹号
  • 只需查询数据库或缓存以获取当前的电子邮件列表并进行检查。
  • @完全正确。看看我在下面发布的答案。

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


【解决方案1】:

您当前的代码正在检查 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 在他的回答中提到的那样

【讨论】:

  • 非常感谢@Shyju,它是有效的,只是一个小错误。对于未来的读者:我们必须使用电子邮件而不是命名 sql 命令,因为我们正在对电子邮件进行测试:var q = "select TOP 1 Email from Client where Email=@Email";
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-02
    • 2021-10-06
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多