zoukankan      html  css  js  c++  java
  • [译]asp-net-core-mvc-ajax-form-requests-using-jquery-unobtrusive

    原文

    全文源码

    开始项目

    项目使用了package.json'文件,添加需要的前端package到项目中。在这我们添加了jquery-ajax-unobstrusive`。

    {
      "version": "1.0.0",
      "name": "asp.net",
      "private": true,
      "devDependencies": {
        "bootstrap": "4.1.3",
        "jquery": "3.3.1",
        "jquery-validation": "1.17.0",
        "jquery-validation-unobtrusive": "3.2.10",
        "jquery-ajax-unobtrusive": "3.2.4"
      }
    }
    

    bundleconfig.json文件用来打包js文件和css文件。问了使用这个打包功能,先安装BuildBundlerMinifer包。

    js类库被打包成了两个不同的文件, vendor-min.jsvendor-validation-min.js

    // Vendor JS
    {
        "outputFileName": "wwwroot/js/vendor.min.js",
        "inputFiles": [
          "node_modules/jquery/dist/jquery.min.js",
          "node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
        ],
        "minify": {
          "enabled": true,
          "renameLocals": true
        },
        "sourceMap": false
    },
    // Vendor Validation JS
    {
        "outputFileName": "wwwroot/js/vendor-validation.min.js",
        "inputFiles": [
          "node_modules/jquery-validation/dist/jquery.validate.min.js",
          "node_modules/jquery-validation/dist/additional-methods.js",
          "node_modules/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js",
          "node_modules//jquery-ajax-unobtrusive/jquery.unobtrusive-ajax.min.js"
        ],
        "minify": {
          "enabled": true,
          "renameLocals": true
        },
        "sourceMap": false
    }
    

    全局打包文件可以添加到_Layout.cshtml文件中。

    <script src="~/js/vendor.min.js" asp-append-version="true"></script>
        <script src="~/js/site.min.js" asp-append-version="true"></script>
        @RenderSection("scripts", required: false)
    </body>
    

    将validation打包文件添加到_ValidationScriptsPartial.cshtml中。

    <script src="~/js/vendor-validation.min.js" asp-append-version="true"></script>
    

    然后就可以将其添加到需要的视图中去。

    @section Scripts  {
        @await Html.PartialAsync("_ValidationScriptsPartial")
    }
    

    简单的AJAX的表单请求

    通过添加一些html attribute到表单元素上可以将一个表单请求作为一个ajax请求发送。当请求结束,id为data-ajax-update指定的div将被替换为相应结果。Html.PartialAsync调用初始的视图。

    @{
        ViewData["Title"] = "Ajax Test Page";
    }
     
    <h4>Ajax Test</h4>
     
    <form asp-action="Index" asp-controller="AjaxTest"
          data-ajax="true"
          data-ajax-method="POST"
          data-ajax-mode="replace"
          data-ajax-update="#ajaxresult" >
     
        <div id="ajaxresult">
            @await Html.PartialAsync("_partialAjaxForm")
        </div>
    </form>
     
    @section Scripts  {
        @await Html.PartialAsync("_ValidationScriptsPartial")
    }
    

    _partialAjaxForm.cshtml视图实现了表单的一些内容。

    @model AspNetCoreBootstrap4Validation.ViewModels.AjaxValidationModel 
     
    <div asp-validation-summary="All" class="text-danger"></div>
     
    <div class="form-group">
      <label for="name">Name</label>
      <input type="text" class="form-control" asp-for="Name"
         id="AjaxValidationModelName" aria-describedby="nameHelp"
         placeholder="Enter name">
      <small id="nameHelp" class="form-text text-muted">
        We'll never share your name ...
      </small>
      <span asp-validation-for="Name" class="text-danger"></span>
    </div>
     
    <div class="form-group">
      <label for="age">Age</label>
      <input type="number" class="form-control"
        id="AjaxValidationModelAge" asp-for="Age" placeholder="0">
      <span asp-validation-for="Age" class="text-danger"></span>
    </div>
     
    <div class="form-check ten_px_bottom">
      <input type="checkbox" class="form-check-input big_checkbox"
          asp-for="IsCool" id="AjaxValidationModelIsCool">
      <label class="form-check-label ten_px_left" for="IsCool">IsCool</label>
      <span asp-validation-for="IsCool" class="text-danger"></span>
    </div>
     
    <button type="submit" class="btn btn-primary">Submit</button>
    

    下面例子中的第一个Index方法,仅用来相应HTTP GET请求。

    第二个Index方法接收一个POST请求,其中包括了每次都会发送的Anti-Forgery token。成功后,返回一个部分视图,并清空model state,否则validation messages不会被重置。

    public class AjaxTestController : Controller
    {
      public IActionResult Index()
      {
        return View(new AjaxValidationModel());
      }
     
      [HttpPost]
      [ValidateAntiForgeryToken]
      public IActionResult Index(AjaxValidationModel model)
      {
        if (!ModelState.IsValid)
        {
          return PartialView("_partialAjaxForm", model);
        }
     
        // the client could validate this, but allowed for testing server errors
        if(model.Name.Length < 3)
        {
          ModelState.AddModelError("name", "Name should be longer than 2 chars");
          return PartialView("_partialAjaxForm", model);
        }
     
        ModelState.Clear();
        return PartialView("_partialAjaxForm");
      }
    }
    

    复杂的ajax表单请求

    这个例子中会返回一个数据集合到视图,每个数据子项都有一个表单用来更新这个子项的数据,通过checkbox的onchange事件,文本框的oninput事件来触发请求。

    因为是一个数据集合,因此每个子项所用的div元素都必须有一个唯一的id。可以通过为每一个子项生成一个GUID来实现,用它作为data-ajax-update的一部分。

    @using AspNetCoreBootstrap4Validation.ViewModels
    @model AjaxValidationListModel
    @{
        ViewData["Title"] = "Ajax Test Page";
    }
     
    <h4>Ajax Test</h4>
     
    @foreach (var item in Model.Items)
    {
        string guid = Guid.NewGuid().ToString();
     
        <form asp-action="Index" asp-controller="AjaxComplexList"
              data-ajax="true"
              data-ajax-method="POST"
              data-ajax-mode="replace"
              data-ajax-update="#complex-ajax-@guid">
     
            <div id="complex-ajax-@guid">
                @await Html.PartialAsync("_partialComplexAjaxForm", item)
            </div>
        </form>
    }
     
     
    @section Scripts  {
        @await Html.PartialAsync("_ValidationScriptsPartial")
    }
    
    @model AspNetCoreBootstrap4Validation.ViewModels.AjaxValidationModel
    @{
        string guid = Guid.NewGuid().ToString();
    }
     
    <div asp-validation-summary="All" class="text-danger"></div>
     
    <div class="form-group">
        <label for="name">Name</label>
     
        <input type="text" class="form-control" asp-for="Name"
          id="AjaxValidationModelName" aria-describedby="nameHelp" placeholder="Enter name"
          oninput="$('#submit-@guid').trigger('submit');">
     
        <small id="nameHelp" class="form-text text-muted">We'll never share your name ...</small>
        <span asp-validation-for="Name" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label for="age">Age</label>
     
        <input type="number" asp-for="Age"
          class="form-control" id="AjaxValidationModelAge" placeholder="0"
          oninput="$('#submit-@guid').trigger('submit');">
     
        <span asp-validation-for="Age" class="text-danger"></span>
    </div>
    <div class="form-check ten_px_bottom">
     
        @Html.CheckBox("IsCool", Model.IsCool,
            new { onchange = "$('#submit-" + @guid + "').trigger('submit');", @class = "big_checkbox" })
     
        <label class="form-check-label ten_px_left" >Check the checkbox to send a request</label>
    </div>
     
    <button style="display: none" id="submit-@guid" type="submit">Submit</button>
    

    控制器的代码和之前的一样。

    using AspNetCoreBootstrap4Validation.ViewModels;
     
    namespace AspNetCoreBootstrap4Validation.Controllers
    {
        public class AjaxComplexListController : Controller
        {
            public IActionResult Index()
            {
                return View(new AjaxValidationListModel {
                    Items = new List<AjaxValidationModel> {
                        new AjaxValidationModel(),
                        new AjaxValidationModel()
                    }
                });
            }
     
            [HttpPost]
            [ValidateAntiForgeryToken]
            public IActionResult Index(AjaxValidationModel model)
            {
                if (!ModelState.IsValid)
                {
                    return PartialView("_partialComplexAjaxForm", model);
                }
     
                // the client could validate this, but allowed for testing server errors
                if(model.Name.Length < 3)
                {
                    ModelState.AddModelError("name", "Name should be longer than 2 chars");
                    return PartialView("_partialComplexAjaxForm", model);
                }
     
                ModelState.Clear();
                return PartialView("_partialComplexAjaxForm", model);
            }
        }
    }
    
  • 相关阅读:
    vue+element ui 实现菜单无限极菜单
    DOM事件绑定原理和传播机制
    数组和对象的深浅克隆
    new源码分析和Object.create的重写
    原型和原型链的学习
    4.3 模型参数的延后初始化
    4.2 模型参数的访问、初始化和共享
    CSAPP Float Point
    4.1 模型构造
    3.16 实战Kaggle比赛:房价预测
  • 原文地址:https://www.cnblogs.com/irocker/p/asp-net-core-mvc-ajax-form-requests-using-jquery-unobtrusive.html
Copyright © 2011-2022 走看看