[英]MVC 5 Remote Validation
在提交表單之前,我需要驗證來自用戶的輸入字段值。
我在我的自定義控制器中創建了一個動作並用它裝飾了該字段:
操作名稱: CheckValue
控制器名稱: Validate
[Remote("CheckValue", "Validate"), ErrorMessage="Value is not valid"]
public string Value { get; set; }
問題是當我按下提交時,表單正在提交,然后如果用戶輸入的值Value is not valid
則會顯示消息Value is not valid
無效。
如果值無效,如何驗證用戶輸入的值並阻止提交表單,並顯示錯誤消息?
如果我嘗試在 JavaScript 中檢查表單是否有效$("#formId").valid()
返回 true,這意味着無論值的狀態(有效與否),表單都是有效的。
另一方面,如果我用[Required]
屬性裝飾另一個字段,則不會提交表單,並且會顯示該字段所需的錯誤。 但是,遠程驗證字段的驗證不會在幕后進行。
MVC中遠程驗證的完整解決方案。 它將檢查電子郵件是否存在於數據庫中並顯示以下錯誤:
電子郵件已經存在
帳戶控制器操作
[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;
添加模型驗證
[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; }
添加腳本
<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>
是的,您必須將[Remote]
添加到您的模型中:
[Remote("ActionName", "ControllerName", ErrorMessage = "{0} Is somthing!")]
public string yourproperty { get; set; }
和控制器:
public JsonResult ActionName(string yourproperty)
{
return Json(!db.yourproperty.Any(lo => lo.yourproperty== yourproperty), JsonRequestBehavior.AllowGet);
}
對我有用; 我希望對你有用。
你不放控制器代碼。 但必須是這樣的:
您的代碼:
[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);
}
}
我們可以使用 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>
現有的答案很好,但有幾個問題:
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);
}
}
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; }
[HttpGet]
public JsonResult IsEmailAvailable(string email)
{
// Check if the e-mail already exists
return Json(!db.Users.Any(x => x.Email == email), JsonRequestBehavior.AllowGet);
}
<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 被禁用時,有兩種方法
在控制器操作方法中動態添加模型驗證錯誤。 修改使用 [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 模型中使用驗證屬性應該是驗證的首選方法。
我在復制和粘貼腳本鏈接時遇到了同樣的問題
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.