MVC 5 Remote Validation

こ雲淡風輕ζ 提交于 2019-11-29 23:04:01
adnan

The complete solution of Remote Validation in 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>
    
Archil Labadze

Yes, you have to add [Remote] to your model:

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

Ali Briceño

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

We can use RemoteAttribute.

Step 1

In the HomeController create a method and for that write the following.

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. We want the validation to occur at the client side, so we are returning a JsonResult.

Step 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

In create.cshtml we need to specify the source of the three jQuery files in the given order.

<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, e.g. for

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

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

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

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

I got the same problem i was copying and pasting script links > problem solved when I drag and drop jquery files from script folder to view page I hope this help.

Remote Validation in MVC

  1. Model Class must have a namespace "System.Web.Mvc" where you have defined the property.
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.
[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.
<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

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

Note:

Remote attribute only works when JavaScript is enabled. If the end-user, disables JavaScript on his/her machine then the validation does not work. This is because RemoteAttribute requires JavaScript to make an asynchronous AJAX call to the server-side validation method. 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:

To make server-side validation work, when JavaScript is disabled, there are 2 ways

  1. Add model validation error dynamically in the controller action method.
  2. Create a custom remote attribute and override IsValid() method.

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]
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. 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. Ideally, all validation logic should be in the Model. Using validation attributes in MVC models should be the preferred method for validation.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!