Reputation: 327
Here I have create form which consists customer email field for which I am trying to check whether the entered email already exits or not and if exist show email already exists message.
To do this i have tried to use remote validation but the problem is that its not showing any error even though email exists, it not even hitting the controller in IsEmailExists
method which is used for remote validation
Any help with my code will be a great help. Thank you
Below is my action in controller
public JsonResult IsEmailExists(string CustomerEmail)
{
emedicineEntities _db = new emedicineEntities();
return Json(!_db.Customers.Any(x => x.CustomerEmail == CustomerEmail), JsonRequestBehavior.AllowGet);
}
Below is my metadata
namespace eMedicine.Model
{
public class CustomerMetaDta
{
[Remote("IsEmailExists", "Customers", ErrorMessage = "EmailId already exists.")]
[Required(ErrorMessage = "Please Enter Emailw")]
public string CustomerEmail { get; set; }
}
}
Below is my partial class
namespace eMedicine.Model
{
[MetadataType(typeof(CustomerMetaDta))]
public partial class Customer
{
}
}
Below is my view consisting customer email
<link href="~/Content/Site.css" rel="stylesheet" />
<script src="~/Scripts/jquery-3.3.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
@using (Html.BeginForm("Create", "Customers", FormMethod.Post, new { @id = "register" }))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.CustomerName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.CustomerName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.CustomerName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.CustomerEmail, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.CustomerEmail, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.CustomerEmail, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.PasswordHash, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.PasswordHash, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.PasswordHash, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
Upvotes: 1
Views: 6911
Reputation: 946
In my case I was missing the following:
@section Scripts {
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"></script>
}
Upvotes: 0
Reputation: 1
I had the same problem the thing is I used Global authentication in program.cs,just use AllowAnonymous Annotation on IsEmailExist(), it will work!
Upvotes: 0
Reputation: 1
//[AcceptVerbs("Get,Post")]
//[AllowAnonymous]
public async Task<IActionResult> IsEmailInUse(string email)
{
var registration = await
_context.Registration.FirstOrDefaultAsync(m => m.Email == email);
if(registration == null)
{
return Json(true);
}
else
{
return Json($"Email {email} is already in use");
}
}
//In Model Class
public class Registration
{
[System.ComponentModel.DataAnnotations.Key]
public int EmpId { get; set; }
public string UserName { get; set; }
[Required]
[EmailAddress]
[Remote(action: "IsEmailInUse",controller: "Registrations")]
public string Email { get; set; }
}
Upvotes: -1
Reputation: 1
You can try to add this code to the bottom of your View:
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
This is the issue I had.
Upvotes: -1
Reputation: 1
One thing no one mentioned which will cause your symptons: If the method needs to be executed by Anonymous users and you don't have the AllowAnonymous attribute on your method, the method will not fire (and the submit button won't do anything.
Upvotes: -1
Reputation: 30443
If it's not hitting the controller that suggests it isn't a problem with the actual validation logic, but more an issue with how you're addressing the server.
There are a few things to check:
The first thing to consider is could this be a security/authentication issue. There are a few simple things you can do to check that:
If that doesn't fix it, then when you've got the app running in debug, try using Postman to call your remote validation endpoint and see whether:
If Postman can get to your endpoint then...
I can't see anything obviously wrong in your code, but it is different to how I write validation code. This is an example of some working remote validation straight out of my code
This is the model property with the remote validation set:
[System.Web.Mvc.Remote(
action: "CheckExistingDocumentCode",
controller: "Documents",
AdditionalFields = "DocumentId",
HttpMethod = "POST",
ErrorMessage = "Code already exists")]
public string DocumentCode { get; set; }
This is the corresponding method in the Documents controller:
[HttpPost]
public async Task<ActionResult> CheckExistingDocumentCode(string DocumentCode, int DocumentId)
{
try
{
if (!await _documentValidationRules.IsExistingDocumentCodeAsync(DocumentCode, DocumentId))
{
return Json(true, JsonRequestBehavior.AllowGet);
}
return Json("This Document Code is already in use", JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(ex.ToString(), JsonRequestBehavior.AllowGet);
}
}
You can see that I've explicitly named all the parameters on the model property just to be clear exactly what's going on.
Comparing my code to yours the main differences are:
HttpPost
attribute, which also means I needed to tell the model the HttpMethod
was POST too)AdditionalFields
argumentI can't see what the issue is in your code, but try changing it a piece at a time to work more like mine (particularly, try making it a post method and naming the parameters) and see if that exposes any issues.
Hopefully something in the above will get you closer.
Upvotes: 1
Reputation: 18975
Not sure what real problem with your source code, but i tried to reproduce in my side, it worked well.
Here are my source code.
namespace WebApplication1.Controllers
{
public class CustomerMetaDta
{
[Remote("IsEmailExists", "Customer", ErrorMessage = "EmailId already exists.")]
[Required(ErrorMessage = "Please Enter Emailw")]
public string CustomerEmail { get; set; }
}
[MetadataType(typeof(CustomerMetaDta))]
public partial class Customer
{
}
public partial class Customer
{
public string CustomerEmail { get; set; }
public string CustomerName { get; set; }
public string PasswordHash { get; set; }
}
public class CustomerController : Controller
{
public JsonResult IsEmailExists(string CustomerEmail)
{
//emedicineEntities _db = new emedicineEntities();
List<Customer> _db = new List<Customer>
{
new Customer { CustomerEmail = "[email protected]"},
new Customer { CustomerEmail = "[email protected]"}
};
return Json(!_db.Any(x => x.CustomerEmail == CustomerEmail), JsonRequestBehavior.AllowGet);
}
// GET: Customer
public ActionResult Index()
{
return View();
}
}
}
Index.cshtml file:
@model WebApplication1.Controllers.Customer
@{
ViewBag.Title = "Index";
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"></script>
@using (Html.BeginForm("Create", "Customer", FormMethod.Post, new { @id = "register" }))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.CustomerName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.CustomerName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.CustomerName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.CustomerEmail, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.CustomerEmail, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.CustomerEmail, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.PasswordHash, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.PasswordHash, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.PasswordHash, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
It jumps to method IsEmailExists() and this is result output
May be you missed setting
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
in web.config?
Upvotes: 1
Reputation: 32069
Change your method signature as follows to include the Bind Prefix
attribute/property.
public JsonResult IsEmailExists([Bind(Prefix="Customer.CustomerEmail")] string CustomerEmail)
{
emedicineEntities _db = new emedicineEntities();
return Json(!_db.Customers.Any(x => x.CustomerEmail == CustomerEmail), JsonRequestBehavior.AllowGet);
}
Now it should work!
Upvotes: 1