24

在提交表单之前,我需要验证用户的输入字段值。

我在我的自定义控制器中创建了一个动作并用它装饰了该字段:

动作名称: CheckValue 控制器名称: Validate

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

问题是当我按下提交时,表单正在提交,Value is not valid如果用户输入的值无效,则会显示消息。

如何验证用户输入的值并在值无效时阻止提交表单并显示错误消息?

如果我尝试在 JavaScript 中检查返回 true 的表单是否有效$("#formId").valid(),这意味着无论值的状态是什么(有效与否),表单都是有效的。

另一方面,如果我用该[Required]属性装饰另一个字段,则不会提交表单,并且会为所需的字段显示错误。但是,远程验证字段的验证不会在后台进行。

4

6 回答 6

36

MVC中远程验证的完整解决方案。它将检查电子邮件是否存在于数据库中并显示以下错误:

电子邮件已经存在

  1. 帐户控制器操作

    [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. 添加模型验证

    [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. 添加脚本

    <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>
    
于 2016-05-25T07:45:34.110 回答
3

您没有放置控制器代码。但必须是这样的:

你的代码:

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

我的控制器代码(验证):

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);
            }
        }
于 2015-05-07T15:44:25.757 回答
2

参考c-sharpcorner demo

我们可以使用 RemoteAttribute。

步骤1

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

您可能想知道为什么我们要返回 JsonResult。我们希望验证发生在客户端,所以我们返回一个 JsonResult。

第2步

下一步是将此方法与用户名属性挂钩,首先我们需要在模型文件夹中添加一个类文件,添加部分用户类并为用户名属性提供所需的自定义。

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

第 3 步

在 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>
于 2017-02-02T19:21:41.087 回答
1

MVC 中的远程验证

  1. 模型类必须有一个命名空间“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. 确保您必须在控制器上实现 IsEmailAvailable Action。
[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. 确保您已在 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>

并从 web.config 启用客户端验证

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

笔记:

远程属性仅在启用 JavaScript 时有效。如果最终用户在他/她的机器上禁用 JavaScript,则验证不起作用。这是因为 RemoteAttribute 需要 JavaScript 对服务器端验证方法进行异步 AJAX 调用。因此,用户将能够提交表单,绕过验证。这就是为什么进行服务器端验证总是很重要的原因。

如果禁用 Javascript:

为了使服务器端验证工作,当 JavaScript 被禁用时,有两种方法

  1. 在控制器操作方法中动态添加模型验证错误。
  2. 创建自定义远程属性并覆盖 IsValid() 方法。

在控制器操作方法中动态添加模型验证错误。修改用 [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);
}

此时,在浏览器中禁用 JavaScript,并测试您的应用程序。请注意,我们没有得到客户端验证,但是当您提交表单时,如果出现验证错误,服务器端验证仍然会阻止用户提交表单。

但是,将执行验证的责任委托给控制器操作方法违反了 MVC 中的关注点分离。理想情况下,所有验证逻辑都应该在模型中。在 MVC 模型中使用验证属性应该是首选的验证方法。

于 2019-08-09T10:03:41.197 回答
1

现有的答案很好,但有几个问题:

1) 验证方法的参数名称必须与正在验证的属性名称完全匹配,例如

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

必须调用验证方法的参数DocumentTypeCode,包括大写字母,否则您将获得 null 作为参数,而不是正在验证的属性的值:

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

如果您是 Resharper 用户,或者您正在编写供多个属性使用的多用途验证方法,请特别注意这一点。

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);
    }
}
于 2018-01-27T22:28:02.467 回答
0

我在复制和粘贴脚本链接时遇到了同样的问题>当我将 jquery 文件从脚本文件夹拖放到查看页面时问题已解决,希望对您有所帮助。

于 2019-05-30T10:36:02.647 回答