当前位置:  开发笔记 > 后端 > 正文

ASP.NET MVC 5表单验证和错误处理

如何解决《ASP.NETMVC5表单验证和错误处理》经验,为你挑选了1个好方法。

尝试在简单的联系表单上实现数据验证和错误处理.当我添加检查ModelState.IsValid我是鸡和鸡蛋的情况.我已经看过其他类似的问题,我只是没有得到这个.从Web Forms迁移到MVC并挣扎.尝试根据正在发生的事情切换HTML元素 - 成功/错误消息等.现在,甚至验证都不起作用.

现在我只是想让服务器端验证工作,但欢迎提供有关如何添加客户端验证的建议; 例如,是否有必要使用jQuery或者有什么内容?

视图:

@using (Html.BeginForm("Contact", "Home", FormMethod.Post))
{
    if (ViewData["Error"] == null && ViewData["Success"] == null)
    {
        

Send us an email

Html.ValidationSummary(true);
} else if (ViewData["Error"] == null && ViewData["Success"] != null) {

We will get back to you as soon as possible!

Thank you for getting in touch with us. If you do not hear from us within 24 hours, that means we couldn't contact you at the email provided. In that case, please feel free to call us at (xxx) xxx-xxxx at any time.

} else if (ViewData["Error"] != null) {

Oops!

We apologize. We seem to be having some problems.

Please come back and try again later. Alternatively, call us anytime at (xxx) xxx-xxxx.

} }

模型:

public class ContactModel
{
    [Required(ErrorMessage = "Email address is required")]
    [EmailAddress(ErrorMessage = "Invalid Email Address")]
    public string Email { get; set; }

    [Required(ErrorMessage = "Subject is required")]
    public string Subject { get; set; }

    [Required(ErrorMessage = "Message is required")]
    public string Message  { get; set; }
}

控制器:

[HttpPost]        
public ActionResult Contact(ContactModel contactModel)
{
    if (ModelState.IsValid)
    {
        try
        {
            MailMessage message = new MailMessage();

            using (var smtp = new SmtpClient("mail.mydomain.com"))
            {
                // Standard mail code here

                ViewData["Success"] = "Success";
             }
         }
         catch (Exception)
         {
             ViewData["Error"] 
                 = "Something went wrong - please try again later.";
                    return View("Error");
         }
     }
     return View();
}

错误视图:




    ModelState.AddModelError("Error", "Server side error occurred");因为我不希望向用户报告系统错误.

另请注意,此时我只在服务器端尝试验证(尚未通过客户端验证).我已经更新了Contact.cshtml视图,因为没有显示任何模型错误 - 我已经包含了验证错误的Bootstrap .has-error.help-blockCSS规则:

@using (Html.BeginForm("Contact", "Home", FormMethod.Post))
{
    

Send us an email

Html.ValidationSummary(true);
@Html.TextBoxFor(m => m.Email, new { type = "text", name = "email", placeholder = "Email..", @class = "contact-email" }) @Html.ValidationMessageFor(model => model.Email, String.Empty, new { @class="help-block" })
@Html.TextBoxFor(m => m.Subject, new { type = "text", name = "subject", placeholder = "Subject..", @class = "contact-subject" }) @Html.ValidationMessageFor(model => model.Subject, String.Empty, new { @class = "help-block" })
@Html.TextAreaFor(m => m.Message, new { name = "message", placeholder = "Message..", @class = "contact-message" }) @Html.ValidationMessageFor(model => model.Message, String.Empty, new { @class = "help-block" })
if (ViewData["Success"] != null) {

We will get back to you as soon as possible!

Thank you for getting in touch with us. If you do not hear from us within 24 hours, that means we couldn't contact you at the email provided. In that case, please feel free to call us at (xxx) xxx-xxxx at any time.

} }

Guruprasad R.. 8

您需要了解多种内容.让我一点一点地走吧.

很高兴知道你有你的model设计,但你的观点如何知道它有一个model自己绑定,当发布form内容时,怎么会server知道,有一个model被接收.所以在第一个实例中,你需要构建你的视图绑定model.要model在a中绑定一个view,你需要首先获得一个引用/在顶部声明它,让视图知道,好的,这是一个model让你生成我的view.

那么,你必须ValidationSummarytrue的话,我会建议,而不是使用ViewData传递错误信息,您可以使用ModelState.AddModelError,让ValidationSummary承担的照顾.作为旁注,您可能还想处理此问题,您可以使用同一帖子中提到的答案解决此问题.如果您不使用或不想使用Html.ValidationSummary,那么您可以坚持使用当前视图.

现在,要显示Success消息,您可以使用TempDataViewData遵循现在视图中的相同结构.这里还有一篇文章可以帮助你解决这个问题.

最后也是最重要的View部分是绑定model属性的属性View.使用Razor View扩展助手View为您的生成model.你有@Html.TextBoxFor,@Html.TextAreaFor等等,你也有@Html.TextBox,@Html.TextArea不是为了绑定model properties,而是为了生成一个平原HTML view.您可以html在其中添加其他属性,helpersview下面更新中所示.我建议更多地了解这些助手可用的重载.

所以这是您的更新视图.

@model SOTestApplication.Models.ContactModel   @*getting model reference*@

@using (Html.BeginForm("Contact", "Home", FormMethod.Post))
{
    

Send us an email

Html.ValidationSummary(true);
@Html.TextBoxFor(m => m.Email, new { type = "text", name = "email", placeholder = "Email..", @class = "contact-email" }) @*Usage of helpers and html attributes*@
@Html.TextBoxFor(m => m.Subject, new { type = "text", name = "subject", placeholder = "Subject..", @class = "contact-subject" })
@Html.TextAreaFor(m => m.Message, new { name = "message", placeholder = "Message..", @class = "contact-message" })
} if (ViewData["Success"] != null) {

We will get back to you as soon as possible!

Thank you for getting in touch with us. If you do not hear from us within 24 hours, that means we couldn't contact you at the email provided. In that case, please feel free to call us at (xxx) xxx-xxxx at any time.

}

控制器侧验证

这部分不多说,因为它看起来不错.但基于我上面提到的几点,我建议你添加ModelState.AddModelError而不是使用ViewData错误消息.消除您的if条件,即使之后仍然存在联系表postback.现在,如果您想在server side验证后保留这些值,那么只需将其传回model给您viewpost方法.更新Controller将是:

[HttpPost]
public ActionResult Contact(ContactModel contactModel)
{
     if (ModelState.IsValid)
     {
          try
          {
              MailMessage message = new MailMessage();
              using (var smtp = new SmtpClient("mail.mydomain.com"))
              {
                  // Standard mail code here
                  ViewData["Success"] = "Success";
              }
          }
          catch (Exception)
          {
              ModelState.AddModelError("Server side error occurred", ex.Message.ToString());
          }
     }
     return View(contactModel); //this will persist user entered data on validation failure
}

客户端验证

考虑到这一部分,您在应用程序中设置的内容很少.

您需要添加Html.EnableClientValidation(true);Html.EnableUnobtrusiveJavaScript(true);应用程序.有各种可能的方法来添加它.您可以在Web.config文件下添加此文件以appSettings获取全局含义或者您可以特别添加此项,view如下面更新的View示例中所述.

Web中的全球含义.Config ex:


  
  

如果您已BundleConfig.csApp_Start目录下注意到您的文件,您会看到默认情况下创建的以下条目.这些是jquery负责客户端验证的东西.

jQueryjQueryVal条目

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                    "~/Scripts/jquery-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.unobtrusive*",
                    "~/Scripts/jquery.validate*"));

下一步是添加对这些文件的引用/用于在任何特定的文件中或在任何特定文件@section Scripts中呈现它们.当你把它包含在内.无论您将其与其他视图一起使用,都会呈现这些脚本/包.所以基本上,你可以在哪里渲染它们.bundles_Layout.cshtmlview_Layout.cshtmllayout

例如,在这里,我会Contact.cshtml view在添加引用之后立即渲染它们model.

@section Scripts
{
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/jqueryval")
}

在这里工作的最后一件事是你需要使用@Html.ValidationMessageForrazor扩展,并MVC在特定属性上绑定错误消息.此外,要在这些错误消息中显示View,您需要ErrorMessage为每个属性指定,model因为您现在正在Required(ErrorMessage=...为每个属性指定model.如果您详细了解这些内容,还有更多需要了解的内容.

添加了适当验证的更新视图.

@model SOTestApplication.Models.ContactModel
@section Scripts
{
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/jqueryval")
}
@using (Html.BeginForm("Contact", "Contacts", FormMethod.Post))
{

    

Send us an email

Html.ValidationSummary(true); Html.EnableClientValidation(true); Html.EnableUnobtrusiveJavaScript(true);
@Html.TextBoxFor(m => m.Email, new { type = "text", name = "email", placeholder = "Email..", @class = "contact-email" }) @Html.ValidationMessageFor(m => m.Email)
@Html.TextBoxFor(m => m.Subject, new { type = "text", name = "subject", placeholder = "Subject..", @class = "contact-subject" }) @Html.ValidationMessageFor(m => m.Subject)
@Html.TextAreaFor(m => m.Message, new { name = "message", placeholder = "Message..", @class = "contact-message" }) @Html.ValidationMessageFor(m => m.Message)
if (ViewData["Success"] != null) {

We will get back to you as soon as possible!

Thank you for getting in touch with us. If you do not hear from us within 24 hours, that means we couldn't contact you at the email provided. In that case, please feel free to call us at (xxx) xxx-xxxx at any time.

} }

希望我已经用这些观点澄清了你的大部分疑虑.快乐的编码.. :)



1> Guruprasad R..:

您需要了解多种内容.让我一点一点地走吧.

很高兴知道你有你的model设计,但你的观点如何知道它有一个model自己绑定,当发布form内容时,怎么会server知道,有一个model被接收.所以在第一个实例中,你需要构建你的视图绑定model.要model在a中绑定一个view,你需要首先获得一个引用/在顶部声明它,让视图知道,好的,这是一个model让你生成我的view.

那么,你必须ValidationSummarytrue的话,我会建议,而不是使用ViewData传递错误信息,您可以使用ModelState.AddModelError,让ValidationSummary承担的照顾.作为旁注,您可能还想处理此问题,您可以使用同一帖子中提到的答案解决此问题.如果您不使用或不想使用Html.ValidationSummary,那么您可以坚持使用当前视图.

现在,要显示Success消息,您可以使用TempDataViewData遵循现在视图中的相同结构.这里还有一篇文章可以帮助你解决这个问题.

最后也是最重要的View部分是绑定model属性的属性View.使用Razor View扩展助手View为您的生成model.你有@Html.TextBoxFor,@Html.TextAreaFor等等,你也有@Html.TextBox,@Html.TextArea不是为了绑定model properties,而是为了生成一个平原HTML view.您可以html在其中添加其他属性,helpersview下面更新中所示.我建议更多地了解这些助手可用的重载.

所以这是您的更新视图.

@model SOTestApplication.Models.ContactModel   @*getting model reference*@

@using (Html.BeginForm("Contact", "Home", FormMethod.Post))
{
    

Send us an email

Html.ValidationSummary(true);
@Html.TextBoxFor(m => m.Email, new { type = "text", name = "email", placeholder = "Email..", @class = "contact-email" }) @*Usage of helpers and html attributes*@
@Html.TextBoxFor(m => m.Subject, new { type = "text", name = "subject", placeholder = "Subject..", @class = "contact-subject" })
@Html.TextAreaFor(m => m.Message, new { name = "message", placeholder = "Message..", @class = "contact-message" })
} if (ViewData["Success"] != null) {

We will get back to you as soon as possible!

Thank you for getting in touch with us. If you do not hear from us within 24 hours, that means we couldn't contact you at the email provided. In that case, please feel free to call us at (xxx) xxx-xxxx at any time.

}

控制器侧验证

这部分不多说,因为它看起来不错.但基于我上面提到的几点,我建议你添加ModelState.AddModelError而不是使用ViewData错误消息.消除您的if条件,即使之后仍然存在联系表postback.现在,如果您想在server side验证后保留这些值,那么只需将其传回model给您viewpost方法.更新Controller将是:

[HttpPost]
public ActionResult Contact(ContactModel contactModel)
{
     if (ModelState.IsValid)
     {
          try
          {
              MailMessage message = new MailMessage();
              using (var smtp = new SmtpClient("mail.mydomain.com"))
              {
                  // Standard mail code here
                  ViewData["Success"] = "Success";
              }
          }
          catch (Exception)
          {
              ModelState.AddModelError("Server side error occurred", ex.Message.ToString());
          }
     }
     return View(contactModel); //this will persist user entered data on validation failure
}

客户端验证

考虑到这一部分,您在应用程序中设置的内容很少.

您需要添加Html.EnableClientValidation(true);Html.EnableUnobtrusiveJavaScript(true);应用程序.有各种可能的方法来添加它.您可以在Web.config文件下添加此文件以appSettings获取全局含义或者您可以特别添加此项,view如下面更新的View示例中所述.

Web中的全球含义.Config ex:


  
  

如果您已BundleConfig.csApp_Start目录下注意到您的文件,您会看到默认情况下创建的以下条目.这些是jquery负责客户端验证的东西.

jQueryjQueryVal条目

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                    "~/Scripts/jquery-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.unobtrusive*",
                    "~/Scripts/jquery.validate*"));

下一步是添加对这些文件的引用/用于在任何特定的文件中或在任何特定文件@section Scripts中呈现它们.当你把它包含在内.无论您将其与其他视图一起使用,都会呈现这些脚本/包.所以基本上,你可以在哪里渲染它们.bundles_Layout.cshtmlview_Layout.cshtmllayout

例如,在这里,我会Contact.cshtml view在添加引用之后立即渲染它们model.

@section Scripts
{
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/jqueryval")
}

在这里工作的最后一件事是你需要使用@Html.ValidationMessageForrazor扩展,并MVC在特定属性上绑定错误消息.此外,要在这些错误消息中显示View,您需要ErrorMessage为每个属性指定,model因为您现在正在Required(ErrorMessage=...为每个属性指定model.如果您详细了解这些内容,还有更多需要了解的内容.

添加了适当验证的更新视图.

@model SOTestApplication.Models.ContactModel
@section Scripts
{
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/jqueryval")
}
@using (Html.BeginForm("Contact", "Contacts", FormMethod.Post))
{

    

Send us an email

Html.ValidationSummary(true); Html.EnableClientValidation(true); Html.EnableUnobtrusiveJavaScript(true);
@Html.TextBoxFor(m => m.Email, new { type = "text", name = "email", placeholder = "Email..", @class = "contact-email" }) @Html.ValidationMessageFor(m => m.Email)
@Html.TextBoxFor(m => m.Subject, new { type = "text", name = "subject", placeholder = "Subject..", @class = "contact-subject" }) @Html.ValidationMessageFor(m => m.Subject)
@Html.TextAreaFor(m => m.Message, new { name = "message", placeholder = "Message..", @class = "contact-message" }) @Html.ValidationMessageFor(m => m.Message)
if (ViewData["Success"] != null) {

We will get back to you as soon as possible!

Thank you for getting in touch with us. If you do not hear from us within 24 hours, that means we couldn't contact you at the email provided. In that case, please feel free to call us at (xxx) xxx-xxxx at any time.

} }

希望我已经用这些观点澄清了你的大部分疑虑.快乐的编码.. :)

推荐阅读
mylvfamily
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有