Skip to main content
 首页 » 编程设计

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

2024年01月29日35Free-Thinker

目标:
如果您根据输入检索错误,它应该显示在与 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 日:有一种简单的方法可以做到这一点

为表单创建一个局部 View ,我们称之为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" />     
} 

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

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

现在在 action 方法中,当模型状态验证失败时,返回分部 View 。

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

现在,当您提交表单并且模型状态验证失败时,操作方法代码将返回带有验证错误消息(由验证助手生成)和 jquery.unobtrusive-ajax.js 的部分 View 结果。库代码将替换(因为我们用 data-ajax-mode="replace" 指定了)jquery 选择器 #data-ajax-update 结果的内容(表单标签及其内部内容)以及从服务器返回的响应。

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


Html.ValidationSummary执行 razor View 时将执行方法。如果您正在执行普通表单发布(非 ajax),则当模型验证失败时(假设您编写了这样的代码)您的操作方法通常会返回到相同的 View 并且执行了 razor View 代码并且 ValidationSummary 方法将读取验证错误来自模型状态字典并呈现错误消息。

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

当您执行 ajax 表单提交时,如果您想要呈现模型验证消息,您需要显式读取模型验证错误并将其作为客户端代码可以读取并显示在 UI 中的 JSON 响应返回。

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

现在在您的 View 中,确保您有一个用于 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" /> 
} 

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

现在创建您的 OnSuccess 函数并检查响应并查看响应是否具有 status 属性并且其值为 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); 
    } 
}