asp.net mvc 项目在使用 Ajax.BeginForm 时不显示带有自定义注释的错误消息
asp.net mvc project does not display error message with custom annotation when using Ajax.BeginForm
\
请尝试建立一个项目,当用户填写时事通讯表格时,
如果电子邮件已经退出,表单应该特别验证输入。
问题在于,当我使用现有电子邮件插入数据时。
自定义注释不会为用户显示错误,它会运行 success ajax 方法,而不是向用户显示错误。
当我使用断点进行调试时,每件事代码都会运行预期的输出,尤其是出现自定义注释的错误消息。
我发现它适用于@Html.BeginForm(),但不适用于@Ajax.BeginForm()
// custom annotation code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using LiveShows.LiveClass;
namespace LiveShows
{
public class CheckEmailAttribute : ValidationAttribute, IClientValidatable
{
public CheckEmailAttribute() :base("{0} Email Already Exit")
{
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if(value != null)
{
var email = value.ToString();
DetailInfo details = new DetailInfo();
bool EmailExit = details.CheckEmailIfExist(email);
if (EmailExit == true)
{
// var ErrorMessage = FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult("Email exist");
}
else
{
return ValidationResult.Success;
}
}
else
{
return new ValidationResult("Field Required");
}
//base.IsValid(value, validationContext);
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule();
rule.ErrorMessage =
FormatErrorMessage(metadata.GetDisplayName());
rule.ValidationType = "checkemail";
yield return rule;
}
}
}
// model code
public class EmailFeedsVm
{
public int id { get; set; }
[Required (ErrorMessage ="Your Name is Required")]
public string DisplayName { get; set; }
[CheckEmail (ErrorMessage ="Email Already Exist")]
[Required (ErrorMessage ="Email field is Required")]
public string Email { get; set; }
public string DateJoined { get; set; }
}
// controller code with actiom
[HttpPost]
public ActionResult NewsLetters(Vmclass.RegisterFeeds fd)
{
if (ModelState.IsValid) {
var feeds = new LiveClass.RegistrationTasks();
bool RegFeeds = feeds.RegisterEmailFeed(
fd.EmailFeeds.DisplayName, fd.EmailFeeds.Email);
if (RegFeeds == true)
{
return View(fd);
}
else
{
return View(fd);
}
}
return View(fd);
}
// javascript code
var EmailMsg = '<h4>Thank You for Joining Us</h4> <p>We will Send You the most Exclusive Events</p>';
function hideLoader(){
loadingUI.attr("style","none")
}
function Success()
{
// hideLoader();
Mymodal.modal('show');
$("#msgHeading").text("Status");
$("#status").html('<img src="../img/com/ok.png" />');
$("#Content").html(EmailMsg);
}
function failure() {
// hideLoader();
Mymodal.modal('show');
msgHeading.text("Status");
$("#status").html('<img src="../img/com/Cancel.png" />');
$("#Content").text("Registration Failed");
}
// view code
<p id="loading" style="display:none">Loading</p>
@using (Ajax.BeginForm("NewsLetters", "Home", new AjaxOptions {
HttpMethod="post",
OnFailure = "failure",
OnSuccess = "Success",
LoadingElementId = "loader",
}, new { id = "getEmail" }))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary()
<div class="form-group">
@Html.LabelFor(a => a.EmailFeeds.DisplayName, "Name", new { @class = "form-label" })
@Html.TextBoxFor(a => a.EmailFeeds.DisplayName, "Email",new {@class = "form-control" })
@Html.ValidationMessageFor(a => a.EmailFeeds.DisplayName)
</div>
<div class="form-group">
@Html.LabelFor(a => a.EmailFeeds.Email, new { @class = "form-label" })
@Html.TextBoxFor(a => a.EmailFeeds.Email, new { @class = "form-control" })
@Html.ValidationMessageFor(a=>a.EmailFeeds.Email)
</div>
<button class="btn btn-blue" id="sendEmail" type="submit" > <img style="display:none" src="../img/ajax-img/smLoader.gif" id="imgBtn" height="25" /> Done! </button>
}
</div>
<div id="notify">
<div class="notify">
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModal-label">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModal-label"> <span id="msgHeading"></span> </h4>
</div>
<div class="modal-body">
<div id="status">
</div>
<div id="Content">
</div>
</div>
<div class="modal-footer">
<div id="msgfooter"></div>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
我在手表选项卡中也看到了这个错误
使用您当前的代码,即使 ModelState.IsValid return 为假,操作方法 return 也是一个查看结果。对于 ajax 调用,这是一个 200 OK 响应,因此转到成功处理程序。
如果视图是 ajax 表单提交,则 return 视图毫无意义。你可以做的是,如果它是一个 ajax 提交,return 一个包含所有模型验证错误的 JSON 响应,并在你的成功处理程序中检查这个 JSON 并显示适当的给用户的错误消息。
[HttpPost]
public ActionResult NewsLetters(Vmclass.RegisterFeeds fd)
{
var list = new List<string>();
if (!ModelState.IsValid)
{
var errors = ViewData.ModelState.Values
.SelectMany(f => f.Errors
.Select(x => new {Error = x.ErrorMessage,
Exception =x.Exception})).ToList();
return Json(new {Status="error",Errors = errors});
}
// to do : Your existing code to save
return Json(new {Status="success"});
}
现在在您的成功句柄中检查
function Success(result) {
if(result.Status==="error")
{
$.each(result.Errors, function(a, b) {
alert(b.Error);
});
}
else
{
$("#status").html("Succesfully saved")
}
}
在这里我只是提醒每个错误。您可以更新该部分以在列表中显示错误并将其附加到 DOM.
如果您希望相同的操作方法用于 ajax 表单提交而不是 ajax 提交,您可以有条件地 return a json response/view结果。 Request.IsAjaxRequest()
方法在这里会派上用场
if(Request.IsAjaxRequest())
{
return Json(new {Status="error",Errors = errors});
}
else
{
return View(fd);
}
\ 请尝试建立一个项目,当用户填写时事通讯表格时, 如果电子邮件已经退出,表单应该特别验证输入。 问题在于,当我使用现有电子邮件插入数据时。 自定义注释不会为用户显示错误,它会运行 success ajax 方法,而不是向用户显示错误。 当我使用断点进行调试时,每件事代码都会运行预期的输出,尤其是出现自定义注释的错误消息。 我发现它适用于@Html.BeginForm(),但不适用于@Ajax.BeginForm()
// custom annotation code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using LiveShows.LiveClass;
namespace LiveShows
{
public class CheckEmailAttribute : ValidationAttribute, IClientValidatable
{
public CheckEmailAttribute() :base("{0} Email Already Exit")
{
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if(value != null)
{
var email = value.ToString();
DetailInfo details = new DetailInfo();
bool EmailExit = details.CheckEmailIfExist(email);
if (EmailExit == true)
{
// var ErrorMessage = FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult("Email exist");
}
else
{
return ValidationResult.Success;
}
}
else
{
return new ValidationResult("Field Required");
}
//base.IsValid(value, validationContext);
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule();
rule.ErrorMessage =
FormatErrorMessage(metadata.GetDisplayName());
rule.ValidationType = "checkemail";
yield return rule;
}
}
}
// model code
public class EmailFeedsVm
{
public int id { get; set; }
[Required (ErrorMessage ="Your Name is Required")]
public string DisplayName { get; set; }
[CheckEmail (ErrorMessage ="Email Already Exist")]
[Required (ErrorMessage ="Email field is Required")]
public string Email { get; set; }
public string DateJoined { get; set; }
}
// controller code with actiom
[HttpPost]
public ActionResult NewsLetters(Vmclass.RegisterFeeds fd)
{
if (ModelState.IsValid) {
var feeds = new LiveClass.RegistrationTasks();
bool RegFeeds = feeds.RegisterEmailFeed(
fd.EmailFeeds.DisplayName, fd.EmailFeeds.Email);
if (RegFeeds == true)
{
return View(fd);
}
else
{
return View(fd);
}
}
return View(fd);
}
// javascript code
var EmailMsg = '<h4>Thank You for Joining Us</h4> <p>We will Send You the most Exclusive Events</p>';
function hideLoader(){
loadingUI.attr("style","none")
}
function Success()
{
// hideLoader();
Mymodal.modal('show');
$("#msgHeading").text("Status");
$("#status").html('<img src="../img/com/ok.png" />');
$("#Content").html(EmailMsg);
}
function failure() {
// hideLoader();
Mymodal.modal('show');
msgHeading.text("Status");
$("#status").html('<img src="../img/com/Cancel.png" />');
$("#Content").text("Registration Failed");
}
// view code
<p id="loading" style="display:none">Loading</p>
@using (Ajax.BeginForm("NewsLetters", "Home", new AjaxOptions {
HttpMethod="post",
OnFailure = "failure",
OnSuccess = "Success",
LoadingElementId = "loader",
}, new { id = "getEmail" }))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary()
<div class="form-group">
@Html.LabelFor(a => a.EmailFeeds.DisplayName, "Name", new { @class = "form-label" })
@Html.TextBoxFor(a => a.EmailFeeds.DisplayName, "Email",new {@class = "form-control" })
@Html.ValidationMessageFor(a => a.EmailFeeds.DisplayName)
</div>
<div class="form-group">
@Html.LabelFor(a => a.EmailFeeds.Email, new { @class = "form-label" })
@Html.TextBoxFor(a => a.EmailFeeds.Email, new { @class = "form-control" })
@Html.ValidationMessageFor(a=>a.EmailFeeds.Email)
</div>
<button class="btn btn-blue" id="sendEmail" type="submit" > <img style="display:none" src="../img/ajax-img/smLoader.gif" id="imgBtn" height="25" /> Done! </button>
}
</div>
<div id="notify">
<div class="notify">
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModal-label">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModal-label"> <span id="msgHeading"></span> </h4>
</div>
<div class="modal-body">
<div id="status">
</div>
<div id="Content">
</div>
</div>
<div class="modal-footer">
<div id="msgfooter"></div>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
我在手表选项卡中也看到了这个错误
使用您当前的代码,即使 ModelState.IsValid return 为假,操作方法 return 也是一个查看结果。对于 ajax 调用,这是一个 200 OK 响应,因此转到成功处理程序。
如果视图是 ajax 表单提交,则 return 视图毫无意义。你可以做的是,如果它是一个 ajax 提交,return 一个包含所有模型验证错误的 JSON 响应,并在你的成功处理程序中检查这个 JSON 并显示适当的给用户的错误消息。
[HttpPost]
public ActionResult NewsLetters(Vmclass.RegisterFeeds fd)
{
var list = new List<string>();
if (!ModelState.IsValid)
{
var errors = ViewData.ModelState.Values
.SelectMany(f => f.Errors
.Select(x => new {Error = x.ErrorMessage,
Exception =x.Exception})).ToList();
return Json(new {Status="error",Errors = errors});
}
// to do : Your existing code to save
return Json(new {Status="success"});
}
现在在您的成功句柄中检查
function Success(result) {
if(result.Status==="error")
{
$.each(result.Errors, function(a, b) {
alert(b.Error);
});
}
else
{
$("#status").html("Succesfully saved")
}
}
在这里我只是提醒每个错误。您可以更新该部分以在列表中显示错误并将其附加到 DOM.
如果您希望相同的操作方法用于 ajax 表单提交而不是 ajax 提交,您可以有条件地 return a json response/view结果。 Request.IsAjaxRequest()
方法在这里会派上用场
if(Request.IsAjaxRequest())
{
return Json(new {Status="error",Errors = errors});
}
else
{
return View(fd);
}