使用Ajax

时间:2017-10-21 20:25:06

标签: c# ajax asp.net-mvc ajax.beginform

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

问题:
我试图做到但它并没有那么好用。

我错过了哪一部分?

谢谢!

的信息:
*我找到了一些网页,但它们并不完全符合我的目的 *我使用的是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; }
    }

}

1 个答案:

答案 0 :(得分:5)

编辑 - 03/11/2017 :有一种简单的方法可以做到这一点

为表单创建一个局部视图,让我们称之为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)

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

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库代码将替换(因为我们用data-ajax-mode="replace"指定了jquery选择器#data-ajax-update的结果内容(表单标签及其内部内容),响应从服务器返回。

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

执行剃刀视图时将执行Html.ValidationSummary方法。如果你正在做一个普通的表单帖子(非ajax),你的动作方法通常在模型验证失败时返回相同的视图(假设你编写类似的代码)并且执行剃刀视图代码并且ValidationSummary方法将读取验证错误从模型状态字典中并呈现错误消息。

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

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

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

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

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