簡體   English   中英

MVC 5 遠程驗證

[英]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中遠程驗證的完整解決方案。 它將檢查電子郵件是否存在於數據庫中並顯示以下錯誤:

電子郵件已經存在

  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>

是的,您必須將[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);
            }
        }

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

現有的答案很好,但有幾個問題:

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 中的遠程驗證

  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 操作。
[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 模型中使用驗證屬性應該是驗證的首選方法。

我在復制和粘貼腳本鏈接時遇到了同樣的問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM