简体   繁体   English

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

[英]Display Error message in Validationsummary with Ajax

Goal: 目标:
If you retrieve a error based on the input, it should be displayed in ValidationSummary in relation to ajax without the webpage being refreshed. 如果您根据输入检索错误,则应在与ajax相关的ValidationSummary中显示该错误,而无需刷新网页。

Problem: 问题:
I have tried to make it but it doesn't work so well. 我试图做到这一点,但是效果不是很好。

What part am I missing? 我缺少哪一部分?

Thank you! 谢谢!

Info: 信息:
*I have found some webpages but they do not fit exactly to my purpose. *我找到了一些网页,但它们与我的目的不完全匹配。
*I'm using ASP.net mvc *我正在使用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; }
    }

}

EDIT - 03/11/2017 : There is an easy way to do this 编辑-03/11/2017 :有一个简单的方法可以做到这一点

Create a partial view for the form, Let's call it Form.cshtml and move the markup needed for the form to that. 为表单创建一个局部视图,我们将其Form.cshtml并将表单所需的标记移至该视图。 For your ajax form, set the data-ajax-mode attribute value to replace and data-ajax-update value to the id of the same form. 对于您的ajax表单,将data-ajax-mode属性值设置为replace并将data-ajax-update值设置为相同表单的ID。

If you are using Ajax.BeginForm helper method, this is how you will do 如果您正在使用Ajax.BeginForm helper方法,这就是您将要做的

@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" />    
}

Now in your main view, simple call this partial view 现在在您的主视图中,简单地称为局部视图

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

Now in the action method, when model state validation fails, return the partial view. 现在在action方法中,当模型状态验证失败时,返回部分视图。

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

Now when you submit the form and model state validation fails, the action method code will return the partial view result with the validation error messages (generated by the validation helpers) and the jquery.unobtrusive-ajax.js library code will replace (because we specified that with data-ajax-mode="replace" ) the content of the result of the jquery selector #data-ajax-update (the form tag and it's inner contents) with the response coming back from the server. 现在,当您提交表单并且模型状态验证失败时,操作方法代码将返回带有验证错误消息的部分视图结果(由验证助手生成),并且jquery.unobtrusive-ajax.js库代码将被替换(因为我们使用data-ajax-mode="replace"来指定jQuery选择器#data-ajax-update的结果的内容(form标记及其内部内容),并从服务器返回响应。

This should do it. 这应该做。 Less client side code, compared to my old approach (below) 与我的旧方法相比,客户端代码更少(如下)


The Html.ValidationSummary method will be executed when the razor view gets executed. Html.ValidationSummary方法将在执行剃刀视图时执行。 If you are doing a normal form post (non ajax), your action method usually returns to the same view when Model validation fails (assuming you write code like that) and the razor view code gets executed and the ValidationSummary method will read the validation errors from the model state dictionary and render the error messages. 如果您执行的是普通表单发布(非ajax),则当模型验证失败时(假设您编写了类似的代码)并且执行了razor视图代码并且ValidationSummary方法将读取验证错误时,您的操作方法通常会返回到同一视图从模型状态字典中提取错误信息。

When you use Ajax.BeginForm helper method the helper will generate some extra data attributes on the form and as long as you have included the jquery.unobtrusive-ajax.min.js script file, the form submit will be hijacked and it will do an ajax form submit instead. 当您使用Ajax.BeginForm辅助方法时,该辅助工具将在表单上生成一些额外的数据属性,并且只要您包含了jquery.unobtrusive-ajax.min.js脚本文件,表单提交将被劫持,并且它将执行而不是ajax表单提交。

When you do the ajax form submit, if you want to render model validation messages, you need to explicitly read the model validation errors and return that as a JSON response which your client side code can read and display in the UI. 在提交ajax表单时,如果要呈现模型验证消息,则需要显式读取模型验证错误,并将其作为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});
  }
}

Now in your view, make sure you have a success handler for your ajax begin form to handle the response json 现在,在您的视图中,确保您有一个成功的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" />
}

Note that i used @Html.ValidationSummary method with 2 overloads and passing an empty string as the first param. 请注意,我将@Html.ValidationSummary方法与2个重载一起使用,并将空字符串作为第一个参数传递。 This will always render a ul element within the div which has class validation-summary-valid . 这将始终在div中呈现一个具有类validation-summary-valid的ul元素。

Now create your OnSuccess function and check the response and see whether response has a status property and the value of it is validationerror . 现在创建您的OnSuccess函数并检查响应,看看响应是否具有status属性,其值是validationerror If yes, loop through the errors collection and add a new li element with the error. 如果是,请遍历错误集合并添加一个包含错误的新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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM