简体   繁体   English

MVC 5 远程验证

[英]MVC 5 Remote Validation

I need to validate an input field value from user before the form is submitted.在提交表单之前,我需要验证来自用户的输入字段值。

I have created an action in my custom controller and decorated the field with it:我在我的自定义控制器中创建了一个动作并用它装饰了该字段:

action name: CheckValue controller name: Validate操作名称: CheckValue控制器名称: Validate

[Remote("CheckValue", "Validate"), ErrorMessage="Value is not valid"]
public string Value { get; set; }

The problem is when I press submit, the form is being submitted and then the message Value is not valid is shown if the value entered by the user is not valid.问题是当我按下提交时,表单正在提交,然后如果用户输入的值Value is not valid则会显示消息Value is not valid无效。

How can I validate the value entered by user and prevent the form to be submitted if value is not valid, and display the error message?如果值无效,如何验证用户输入的值并阻止提交表单,并显示错误消息?

If I try in JavaScript to check if the form is valid $("#formId").valid() that returns true, that means no matter what is the status of the value (valid or not) the form is valid.如果我尝试在 JavaScript 中检查表单是否有效$("#formId").valid()返回 true,这意味着无论值的状态(有效与否),表单都是有效的。

In the other hand if I decorate another field with the [Required] attribute the form is not submitted and the error is shown for that field that is required.另一方面,如果我用[Required]属性装饰另一个字段,则不会提交表单,并且会显示该字段所需的错误。 However the validation doesn't occur behind the scene for the remote validation field.但是,远程验证字段的验证不会在幕后进行。

The complete solution of Remote Validation in MVC. MVC中远程验证的完整解决方案。 It will check if the email exists in database and show the following error:它将检查电子邮件是否存在于数据库中并显示以下错误:

Email already exists电子邮件已经存在

  1. Account Controller Action帐户控制器操作

    [AllowAnonymous] [HttpPost] public ActionResult CheckExistingEmail(string Email) { try { return Json(!IsEmailExists(Email)); } catch (Exception ex) { return Json(false); } } private bool IsEmailExists(string email) => UserManager.FindByEmail(email) != null;
  2. Add Model Validation添加模型验证

    [Required] [MaxLength(50)] [EmailAddress(ErrorMessage = "Invalid Email Address")] [System.Web.Mvc.Remote("CheckExistingEmail", "Account", HttpMethod = "POST", ErrorMessage = "Email already exists")] public string Email { get; set; }
  3. Add Scripts添加脚本

    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

Yes, you have to add [Remote] to your model: 是的,您必须将[Remote]添加到您的模型中:

[Remote("ActionName", "ControllerName", ErrorMessage = "{0} Is somthing!")]
public string yourproperty { get; set; }

And Controller: 和控制器:

public JsonResult ActionName(string yourproperty)
{
    return Json(!db.yourproperty.Any(lo => lo.yourproperty== yourproperty), JsonRequestBehavior.AllowGet);
}

Works for me fine; 对我有用; I hope will useful for you. 我希望对你有用。

You dont put the Controller code.你不放控制器代码。 But must to be something like this:但必须是这样的:

Your code:您的代码:

[Remote("CheckValue", "Validate", ErrorMessage="Value is not valid")]
public string Value { get; set; }

My code for the controller(Validate):我的控制器代码(验证):

public ActionResult CheckValue(string Value)
        {
            if (Value == "x value")
            {
        // This show the error message of validation and stop the submit of the form
                return Json(true, JsonRequestBehavior.AllowGet);
            }
            else
            {
        // This will ignore the validation and the submit of the form is gone to take place.
               return Json(false, JsonRequestBehavior.AllowGet);
            }
        }

With the reference of c-sharpcorner demo参考c-sharpcorner demo

We can use RemoteAttribute.我们可以使用 RemoteAttribute。

Step 1第1步

In the HomeController create a method and for that write the following.在 HomeController 中创建一个方法并为此编写以下内容。

public JsonResult IsUserExists(string UserName)   
{  
//check if any of the UserName matches the UserName specified in the Parameter using the ANY extension method.  
return Json(!db.Users.Any(x => x.UserName == UserName) ,JsonRequestBehavior.AllowGet);  
}  

You might be wondering why we are returning JsonResult back.您可能想知道为什么我们要返回 JsonResult。 We want the validation to occur at the client side, so we are returning a JsonResult.我们希望在客户端进行验证,因此我们返回一个 JsonResult。

Step 2第2步

The next step is to hook this method up with the username property and for that first we need to add a class file in the models folder, add a partial User class and provide the required customization to the UserName property.下一步是将此方法与用户名属性挂钩,为此首先我们需要在模型文件夹中添加一个类文件,添加一个部分用户类并为用户名属性提供所需的自定义。

using System.ComponentModel.DataAnnotations;  
using System.Web.Mvc;   
namespace UniqueField.Models 
{  
   [MetadataType(typeof(UserMetaData))]  
   public partial class User 
   {  
   }  
class UserMetaData 
{  
   [Remote("IsUserExists","Home",ErrorMessage="User Name already in use")]  
   public string UserName { get; set; }  
}  
}  

Step 3第 3 步

In create.cshtml we need to specify the source of the three jQuery files in the given order.在 create.cshtml 中,我们需要按照给定的顺序指定三个 jQuery 文件的来源。

<h2>Create</h2>  
<script src="~/Scripts/jquery-1.10.2.js"></script>  
<script src="~/Scripts/jquery.validate.js"></script>  
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>

The existing answers are great but there are a couple of gotchas:现有的答案很好,但有几个问题:

1) The validation method's parameter name has to exactly match the name of the property being validated, eg for 1) 验证方法的参数名称必须与被验证的属性名称完全匹配,例如对于

[System.Web.Mvc.Remote("CheckExistingDocumentTypeCode", "DocumentTypes", HttpMethod = "POST", ErrorMessage = "Code already exists")]
public string DocumentTypeCode { get; set; }

The validation method's parameter must be called DocumentTypeCode , including the capital letter, or else you'll get a null as the parameter instead of the value of the property being validated:验证方法的参数必须被称为DocumentTypeCode ,包括大写字母,否则您将得到一个 null 作为参数而不是被验证的属性的值:

[AllowAnonymous]
[HttpPost]
public async Task<ActionResult> CheckExistingDocumentTypeCode(string DocumentTypeCode)

Be particularly wary of this if you are a Resharper user, of if you're writing multipurpose validation methods for use by more than one property.如果您是 Resharper 用户,请特别注意这一点,如果您正在编写供多个属性使用的多用途验证方法。

2) I had to get this working with a Telerik grid and I had to implement it slightly differently in order to get the validation failure messages to show correctly in the grid (the examples here showed 'false' as the validation error message): 2)我必须使用 Telerik 网格来实现它,并且我必须稍微不同地实现它,以便在网格中正确显示验证失败消息(此处的示例显示“false”作为验证错误消息):

[AllowAnonymous]
[HttpPost]
public async Task<ActionResult> CheckExistingDocumentTypeCode(string DocumentTypeCode)
{
    try
    {
        if (!await IsDocTypeCodeExists(DocumentTypeCode))
        {
            return Json(true, JsonRequestBehavior.AllowGet);
        }
        return Json("This Document Type Code is already in use", JsonRequestBehavior.AllowGet);
    }
    catch (Exception ex)
    {
        return Json(ex.ToString(), JsonRequestBehavior.AllowGet);
    }
}

Remote Validation in MVC MVC 中的远程验证

  1. Model Class must have a namespace "System.Web.Mvc" where you have defined the property.模型类必须有一个命名空间“System.Web.Mvc”,您已经在其中定义了属性。
using System.Web.Mvc;

[Required(ErrorMessage = "E-mail is required")]
[RegularExpression(@"^[a-zA-Z0-9_\.-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,6}$", ErrorMessage = "Email is not valid")]
[StringLength(30, ErrorMessage = "Email must not be more than 30 char")]
[Remote("IsEmailAvailable", "User", ErrorMessage = "E-mail already in use")]
public string Email { get; set; }
  1. Make sure you have to implement IsEmailAvailable Action on the Controller.确保您必须在控制器上实现 IsEmailAvailable 操作。
[HttpGet]
public JsonResult IsEmailAvailable(string email)
{
    // Check if the e-mail already exists
    return Json(!db.Users.Any(x => x.Email == email), JsonRequestBehavior.AllowGet);
}
  1. Make sure you have added this js on View for client-side validation.确保您已在 View 上添加此 js 以进行客户端验证。
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>

and also enable client-side validation from web.config并从 web.config 启用客户端验证

<appSettings>
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

Note:笔记:

Remote attribute only works when JavaScript is enabled.远程属性仅在启用 JavaScript 时有效。 If the end-user, disables JavaScript on his/her machine then the validation does not work.如果最终用户在他/她的机器上禁用 JavaScript,则验证不起作用。 This is because RemoteAttribute requires JavaScript to make an asynchronous AJAX call to the server-side validation method.这是因为 RemoteAttribute 需要 JavaScript 对服务器端验证方法进行异步 AJAX 调用。 As a result, the user will be able to submit the form, bypassing the validation in place.因此,用户将能够提交表单,绕过验证。 This why it is always important to have server-side validation.这就是为什么进行服务器端验证总是很重要的原因。

In case when Javascript is disabled:如果禁用 Javascript:

To make server-side validation work, when JavaScript is disabled, there are 2 ways为了使服务器端验证工作,当 JavaScript 被禁用时,有两种方法

  1. Add model validation error dynamically in the controller action method.在控制器操作方法中动态添加模型验证错误。
  2. Create a custom remote attribute and override IsValid() method.创建自定义远程属性并覆盖 IsValid() 方法。

Adding model validation error dynamically in the controller action method.在控制器操作方法中动态添加模型验证错误。 Modify the Create action method that is decorated with [HttpPost] attribute as shown below.修改使用 [HttpPost] 属性修饰的 Create action 方法,如下所示。

[HttpPost]
public ActionResult Create(User user)
{
    // Check if the Email already exists, and if it does, add Model validation error
    if (db.Users.Any(x => x.Email == user.Email))
    {
        ModelState.AddModelError("Email", "Email already in use");
    }
    if (ModelState.IsValid)
    {
        db.Users.AddObject(user);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(user);
}

At this point, disable JavaScript in the browser, and test your application.此时,在浏览器中禁用 JavaScript,并测试您的应用程序。 Notice that, we don't get client-side validation, but when you submit the form, server-side validation still prevents the user from submitting the form, if there are validation errors.请注意,我们不会获得客户端验证,但是当您提交表单时,如果存在验证错误,服务器端验证仍会阻止用户提交表单。

However, delegating the responsibility of performing validation, to a controller action method violates the separation of concerns within MVC.但是,将执行验证的责任委托给控制器操作方法违反了 MVC 中的关注点分离。 Ideally, all validation logic should be in the Model.理想情况下,所有验证逻辑都应该在模型中。 Using validation attributes in MVC models should be the preferred method for validation.在 MVC 模型中使用验证属性应该是验证的首选方法。

我在复制和粘贴脚本链接时遇到了同样的问题

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

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