简体   繁体   English

远程验证ASP MVC中的唯一性

[英]Remote Validation of Uniqueness in ASP MVC

Using ASP MVC and SQL Server, I am trying to test the existence of a client before creating him via the uniqueness of his Email's value. 使用ASP MVC和SQL Server,我试图在通过其电子邮件值的唯一性创建客户端之前测试客户端的存在。

Following a lot of tutorials and solutions, I didn't success to resolve this problem. 经过大量的教程和解决方案,我未能成功解决此问题。 This is what I've tried : 这是我尝试过的:

ClientController : 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;
    }

Model Client : 模特客户:

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

View Create : 查看创建:

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

You need to add a unique constraint or unique index on Email in the database. 您需要在数据库中的电子邮件上添加唯一约束或唯一索引。

Even when you check for existence before the insert, concurrent requests could lead to duplicates. 即使在插入之前检查是否存在,并发请求也可能导致重复。 So have the database enforce uniqueness and handle the error it returns when you try to insert a duplicate. 因此,让数据库强制唯一性并处理尝试插入重复项时返回的错误。

Your current code is checking againist an empty list of Client . 您当前的代码再次检查Client的空列表。 You should be checking against existing data. 您应该检查现有数据。

You can write a method to check that 您可以编写一种方法来检查

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

Now you call this method in your other method. 现在,您可以在其他方法中调用此方法。 Your IsClientExist should return false when the email exist in the system and should return true when it does not exist in the database . 当电子邮件存在于系统中时, IsClientExist应该返回false ,而在数据库中不存在时应返回true So basically you need to negate the result coming back from the DoesEmailExist method 因此,基本上,您需要否定来自DoesEmailExist方法返回的结果

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

Keep in mind that this does only Client side validation. 请记住,这仅进行客户端验证。 Never trust data coming from client.Always validate on server side . 永远不要信任来自客户端的数据。始终在服务器端进行验证 You should add database level constraints to prevent duplicate emails getting saved in the table as @David Browne mentioned in his answer 您应该添加数据库级别约束,以防止重复的电子邮件被保存在表中,就像@David Browne在他的回答中提到的那样

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM