使用 Ajax 在 Validationsummary 中显示错误消息

Display Error message in Validationsummary with Ajax

目标:
如果您根据输入检索错误,它应该显示在与 ajax 相关的 ValidationSummary 中,而无需刷新网页。

问题:
我试过了,但效果不太好。

我错过了什么?

谢谢!

信息:
*我找到了一些网页,但它们并不完全符合我的目的。
*我正在使用 ASP.net mvc

@model WebApplication1.Controllers.PersonnelModel

@{
    ViewBag.Title = "Ajax";
}

<h2>Ajax</h2>



<h2>AjaxViewModel</h2>
@using (Html.BeginForm("HtmlViewModel", "Home", null))
{
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>PersonnelModel</legend>
        <div class="editor-label">
            @Html.LabelFor(model => model.UserName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.UserName)
            @Html.ValidationMessageFor(model => model.UserName)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.MailAdress)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.MailAdress)
            @Html.ValidationMessageFor(model => model.MailAdress)
        </div>
    </fieldset>
    <p>
        <input type="submit" value="Html Form Action" />
    </p>
}

<br/>
<br />




<h2>AjaxViewModel</h2>
@using (Ajax.BeginForm("AjaxViewModel", "Home", new AjaxOptions { UpdateTargetId = "result" }))
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>PersonnelModel</legend>

        <div id="result"></div>
        <div class="editor-label">
            @Html.LabelFor(model => model.UserName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.UserName)
            @Html.ValidationMessageFor(model => model.UserName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.MailAdress)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.MailAdress)
            @Html.ValidationMessageFor(model => model.MailAdress)
        </div>
    </fieldset>
    <p>
        <input type="submit" value="Ajax Form Action" />
    </p>
}



<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-ajax-unobtrusive@3.2.4/jquery.unobtrusive-ajax.min.js"></script>

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;

namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }


        [HttpPost]
        public ActionResult HtmlViewModel(PersonnelModel Pmodel)
        {
            return Content("Hi " + Pmodel.UserName + ", Thanks for the details, a mail will be sent to " + Pmodel.MailAdress + " with all the login details.", "text/html");
        }


        [HttpPost]
        public ActionResult AjaxViewModel(PersonnelModel Pmodel)
        {
            /*
            ModelState.AddModelError("", "login is fail");
            return View("Index", Pmodel);
            */

            return Content("Hi " + Pmodel.UserName + ", Thanks for the details, a mail will be sent to " + Pmodel.MailAdress + " with all the login details.", "text/html");
        }

    }



    public class PersonnelModel
    {
        [Required(ErrorMessage = "UserName Required.")]
        public string UserName { get; set; }

        [Required(ErrorMessage = "Email id Required.")]
        public string MailAdress { get; set; }
    }

}

编辑 - 2017 年 3 月 11 日:有一种简单的方法可以做到这一点

为表单创建一个局部视图,我们将其命名为 Form.cshtml 并将表单所需的标记移至该视图。对于您的 ajax 表单,将 data-ajax-mode 属性值设置为 replace 并将 data-ajax-update 值设置为同一表单的 ID。

如果您使用的是 Ajax.BeginForm 辅助方法,这就是您要执行的操作

@model PersonnelModel
@using (Ajax.BeginForm("Create", "Home", 
     new AjaxOptions { UpdateTargetId = "myform", 
                              InsertionMode = InsertionMode.Replace },new { id="myform"}))
{
    @Html.ValidationSummary("", true)

    @Html.TextBoxFor(f => f.UserName)
    @Html.ValidationMessageFor(model => model.UserName)

    @Html.TextBoxFor(f => f.MailAdress)
    @Html.ValidationMessageFor(model => model.MailAdress)

    <input type="Submit" id="submit" value="Submit" class="btn btn-default" />    
}

现在在你的主视图中,简单调用这个局部视图

@model PersonnelModel
<h2>My form below</h2>
@Html.Partial("Form",Model)

现在在操作方法中,当模型状态验证失败时,return 局部视图。

public ActionResult Create(PersonnelModel model)
{
   if (ModelState.IsValid)
   {
      // to do : Save
   }
   if (Request.IsAjaxRequest())
   {
      return PartialView("Form",model);
   }
   return View(model);
}

现在,当您提交表单和模型状态验证失败时,操作方法代码将 return 带有验证错误消息(由验证助手生成)和 jquery.unobtrusive-ajax.js 的部分视图结果库代码将用从服务器。

这应该可以做到。与我的旧方法(下)相比,客户端代码更少


当执行 razor 视图时,将执行 Html.ValidationSummary 方法。如果你正在做一个正常的形式post(非ajax),当模型验证失败时你的操作方法通常returns到相同的视图(假设你写这样的代码)和剃刀查看代码被执行,ValidationSummary 方法将从模型状态字典中读取验证错误并呈现错误消息。

当你使用 Ajax.BeginForm 辅助方法时,辅助方法会在表单上生成一些额外的数据属性,只要你包含了 jquery.unobtrusive-ajax.min.js 脚本文件,表单提交就会被劫持,它将改为提交 ajax 表单。

当您执行 ajax 表单提交时,如果您想要呈现模型验证消息,您需要明确读取模型验证错误和 return 作为 JSON 响应您的客户端代码可以在 UI.

中读取和显示
[HttpPost]
public ActionResult Index(PersonnelModel  model)
{
  if (ModelState.IsValid)
  {
      return Json(new {status = "success", message= "Thanks for the details"});
  }
  else
  {
     var errors = new List<string>();
     foreach (var modelStateVal in ViewData.ModelState.Values)
     {
        errors.AddRange(modelStateVal.Errors.Select(error => error.ErrorMessage));
     }
     return Json(new {status = "validationerror", errors = errors});
  }
}

现在在您看来,请确保您的 ajax 开始表单有一个成功处理程序来处理响应 json

@using (Ajax.BeginForm("Index", "Home", new AjaxOptions { OnSuccess = "OnSuccess", }))
{
    @Html.ValidationSummary("", true)
    @Html.TextBoxFor(model => model.MailAdress)

    <!--Your other form input elements-->
     <input type="submit" value="Html Form Action" />
}

请注意,我使用了带有 2 个重载的 @Html.ValidationSummary 方法,并传递了一个空字符串作为第一个参数。这将始终在具有 class validation-summary-valid.

的 div 中呈现一个 ul 元素

现在创建您的 OnSuccess 函数并检查响应并查看响应是否具有状态 属性 以及它的值为 validationerror。如果是,循环遍历错误集合并添加一个包含错误的新 li 元素。

function OnSuccess(response) {
    var $summaryUl = $(".validation-summary-valid").find("ul");
    $summaryUl.empty();

    if (response.status === 'validationerror') {
        $.each(response.errors,
            function(a, b) {
                $summaryUl.append($("<li>").text(b));
            });
    } else {
        alert(response.message);
    }
}