【问题标题】:bootstrap modal+ajax+jquery+validation+.net core 2.0引导模式+ajax+jquery+validation+.net core 2.0
【发布时间】:2018-09-15 14:54:39
【问题描述】:

我正在尝试创建一个简单的电影数据库类型的应用程序来学习引导程序和 mvc。我在 .net core 2.0 中使用了 adminlte 模板。仅使用 mvc 一切正常。但后来我想了解更多,所以我开始使用 ajax 和 jquery 来发送和接收数据。对于创建/编辑/,我使用了引导模式。这是我的主要问题。我可以从客户端验证。但我无法在服务器端验证期间显示错误消息。

_Layout.cshtml

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>@ViewData["Title"]</title>
    <!-- Tell the browser to be responsive to screen width -->
    <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">

    <!-- Bootstrap 3.3.7 -->
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css">
    <!-- Font Awesome -->
    <link rel="stylesheet" href="~/lib/font-awesome/css/font-awesome.min.css">
    <!-- Ionicons -->
    <link rel="stylesheet" href="~/lib/Ionicons/css/ionicons.min.css">
    <!-- Theme style -->
    <link rel="stylesheet" href="~/lib/adminlte/dist/css/AdminLTE.min.css">
    <!-- AdminLTE Skins. Choose a skin from the css/skins
         folder instead of downloading all of them to reduce the load. -->
    <link rel="stylesheet" href="~/lib/adminlte/dist/css/skins/skin-blue.min.css">

    <link rel="stylesheet" href="~/css/site.min.css" />
    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <!-- Google Font -->
    @*<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic">*@

    <!-- jQuery 3 -->
    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
    <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
    <!-- Bootstrap 3.3.7 -->
    <script src="~/lib/bootstrap/dist/js/bootstrap.min.js"></script>
    <!-- SlimScroll -->
    <script src="~/lib/jquery-slimscroll/jquery.slimscroll.min.js"></script>
    <!-- FastClick -->
    <script src="~/lib/fastclick/lib/fastclick.js"></script>
    <!-- AdminLTE App -->
    <script src="~/lib/adminlte/dist/js/adminlte.min.js"></script>
    <script src="~/lib/PACE/pace.min.js"></script>
    <script src="~/js/site.min.js"></script>
</head>
<body class="hold-transition skin-blue sidebar-mini">
    <!-- Site wrapper -->
    <div class="wrapper">

        <!-- Top Menubar -->
        @await Component.InvokeAsync("TopMenubar")

        <!-- Left side column. contains the sidebar -->
        @await Component.InvokeAsync("Sidebar")

        <!-- Content Wrapper. Contains page content -->

        <div class="content-wrapper">
            <section class="content-header">
                @await Component.InvokeAsync("ContentHeader")
                <br />
                @await Component.InvokeAsync("Alert")
            </section>

            <section class="content">
                @RenderBody()
            </section>
        </div>

        <!-- Footer -->
        @await Component.InvokeAsync("Footer")

    </div>
    <!-- ./wrapper -->
    @RenderSection("scripts", required: false)
    <script>

    </script>
    @*<script>
            $(document).ready(function () {
                $('.sidebar-menu').tree()
            })
        </script>*@
</body>
</html>

索引.cshtml

@model MovieDb.Models.CategoryType

@{
    ViewData["Title"] = "Category Type";
}

<link rel="stylesheet" href="~/lib/datatables.net-bs/css/dataTables.bootstrap.min.css" />
<script src="~/lib/datatables.net/js/jquery.dataTables.min.js"></script>
<script src="~/lib/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
<script src="~/js/categoryType.js"></script>


<div class="panel">
    <div class="panel-body">
        <button class="btn btn-primary" type="button" data-toggle="modal" data-target="#createNewEmergencyType"
                onclick="clearTextBox();"><i class="fa fa-plus"> Add New Category</i></button>
    </div>
</div>

<div class="box">
    <div class="box-body table-responsive">
        <table id="DgCategoryType" class="table table-bordered table-striped dataTable" role="grid">
            <thead>
                <tr>
                    <th>Name</th>
                    <th></th>
                </tr>
            </thead>
        </table>
    </div>
</div>
<div class="modal fade" id="createNewCategoryType" tabindex="-1" role="dialog"
     aria-labelledby="Add New Category" aria-hidden="true">
     <div class="modal-dialog">
         <div class="modal-content">

             <div class="modal-header">
                 <button type="button" class="close" data-dismiss="modal">
                     &times;
                 </button>
                 <h4 class="modal-title">Add New Category</h4>
             </div>

             <div class="modal-body">
                 <form id="createCTForm">
                     @Html.AntiForgeryToken()

                     <div class="form-group">
                         <label asp-for="Name" class="control-label">Name:</label>
                         <input asp-for="Name" class="form-control" />
                         <span asp-validation-for="Name" class="text-danger"></span>
                     </div>

                 </form>
             </div>

             <div class="modal-footer">
                 <button type="button" class="btn btn-primary btn-fixed-width" id="btnAdd" onclick="return Add();">
                     Add
                 </button>
                 <button type="button" class="btn btn-default btn-fixed-width" data-dismiss="modal">
                     Close
                 </button>
             </div>
         </div>
     </div>

</div>

categoryType.js

$(document).ready(function(){
loadData();
});

function loadData(){
    $("#DgCategoryType").DataTable(

        {           
            "filter": true,
            "orderMulti": false,
            "ajax":
            {
                "url":"/CategoryTypes/LoadData",
                "type":"GET",
                "dataType":"JSON"
            },
            "columns":[
                {"data":"Name"},
                {   "data":"Id",
                    "render":function(data){
                        return "<a class='popup' href='/CategoryTypes/Edit/"+data+"'>Edit</a> | <a class='popup' href='/CategoryTypes/Delete/"+data+"'>Delete</a>";
                    }
                }
            ],
            "columnDefs":
            [
                {
                    "targets": [1],
                    "searchable": false
                },
                {"width":"10%","targets":[1]}
            ]
        }
    );
}

function Add(){

    /*var frm=document.getElementById("createCTForm");
    var data=toJSONString(frm);*/

    var data=$("#createCTForm").serialize();

    $.ajax({
        type:"POST",
        url:"CategoryTypes/Create",
        data:data,
        success:function(result){
            if(result.success)
            {
                $("#createNewCategoryType").modal("hide");
            }
        },
    });
}

function clearTextBox(){
    $("#Name").val("");
}

型号:CategoryType.cs

public class CategoryType
{
    public int Id { get; set; }
    [Required(ErrorMessage ="Category name required")]
    public string Name { get; set; }
}

CategoryTypesController.cs

public class CategoryTypesController : BaseController
    {
        private readonly ApplicationDbContext _context;

        public CategoryTypesController(ApplicationDbContext context)
        {
            _context = context;
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
                _context.Dispose();
            base.Dispose(disposing);
        }

        // GET: CategoryTypes
        public IActionResult Index()
        {
            AddPageHeader("Category Types");
            return View(new CategoryType());
        }

        //GET JSON data for loading the datatable
        public async Task<IActionResult> LoadData()
        {
            var data = await _context.CategoryTypes.ToListAsync();
            return Json(new { data } );
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("Id,Name")] CategoryType categoryType)
        {
            if (ModelState.IsValid)
            {
                _context.Add(CategoryType);
                await _context.SaveChangesAsync();
                return Json(new { success=true });
            }
                return Json(new { success=false });
        }
    }

当我运行上面的代码时,它会将新类别添加到数据库中,但是如果我没有在模式输入框中输入名称,那么控制器会给出错误但不会出现验证消息。

我做错了什么?

【问题讨论】:

    标签: javascript c# asp.net twitter-bootstrap-3 asp.net-core


    【解决方案1】:

    我最近遇到了同样的问题。为了解决这个问题,我亲自处理了这个问题,并创建了一个迷你库(如果你可以这样称呼它)来验证输入。 请从this JsFiddle 获取代码。 您可以在同一链接中找到一个工作示例。

    注意:截至目前,它已检查:必需、正则表达式、范围、等于。 如果您需要帮助,您可以自行添加更多检查,或发表评论,我会尽力提供帮助。

    它是如何工作的:

    1.在您的项目中创建一个 js 文件并从 fiddle 链接粘贴 js(最小代码由区域 CustomValidationScript 表示)。将此文件包含在您的 _layout.cshtml 中。

    2.设置一些规则:

        var validationRules = [{ 
            ruleName: "elementId1ShoudBeRequired", // make sure this 
            name will be unique within your rules 
            ruleForElementId: "#elementId1",
            check: "required",
            comparerValue: true,
            message: "This input is required! Please make sure to input a value!"
        },
        {
            ruleName: "elementId3ShouldBePhoneNr",
            ruleForElementId: "#elementId2",
            check: "regex",
            comparerValue: /^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$/,
            message: "Please provide a valid phone number!"
        },
        {
            ruleName: "elementId4_ShouldBeEqualWith_5",
            ruleForElementId: "#elementId2",
            check: "equals",
            comparerValue: 5,
            message: "This input should be 5!"
        }
        ];
        var rangeRules = [{
            ruleName: "elementId2ShoudBeInRange",
            ruleForElementId: "#elementId2",
            check: "range",
            comparerValue: [1, 8],
            message: "Please provide a value between 1 and 8 !"
        }];
    
    1. 在您的 js 文件/脚本中,在 $(document).ready() 函数之外初始化验证器:

       var validator = new CustomValidation(validationRules);
       // you can pass the validation rules in the initialization, or send a empty array if you wish to add the rules later
       // var validator = new CustomValidation([]);
      
    2. (可选步骤)添加或删除更多验证规则:

       // Add rules
       // you can add them by passing an array of rules
       validator.addcustomValidationRules(rangeRules);
       // or by passing one rule
       validator.addcustomValidationRule(
           {
               ruleName: addRule.ruleName,
               ruleForElementId: addRule.ruleForElementId,
               check: addRule.check,
               comparerValue: addRule.comparerValue,
               message: addRule.message
           }
       );
       // if the rule(s) already exist(s), an error will be thrown
      
       // Remove rules
       // you can also remove some rules by ruleName, or sending an array of rules
       // for example we can remove rangeRules entirely like : 
       validator.removeCustomValidationRules(rangeRules);
       // or we can remove individual rules by name like so: 
       validator.removeCustomValidationRule("elementId2ShoudBeInRange");
      
    3. 验证输入:

      var result = validator.validate(validator); // will return an object like this:{ formIsvalid : true / false, validationResults: [ {elementId: elementId,message: message}] }

      HTML 页面示例:

       <div class="container">
       <div class="form-group">
           <label>Input for elementId1 </label>
           <input id="elementId1" class="validate" />
           <span class="error_span col-md-12"></span>
       </div>
       <div class="form-group">
           <label>Input for elementId2 </label>
           <input id="elementId2" class="validate" />
           <span class="error_span"></span>
       </div>
       <button class="btn btn-outline-success" id="save">Save</button>
       </div>
      
       <script type="text/javascript">
       // you can validate the input inside listeners or inside whatever pieces of code
      
       // example onClick
       $("#save").on("click", function() {
           // the validation happerns here
           var result = validator.validate(validator);
           if (result.formIsValid) {
               // your code ...  
               // can be ajax call to send the form to the server
           }
           else {
               // clear error_spans that might have been fixed between clicks
               updateUi(result.validationResults, "form-group", "error_span");
           }
       });
      
       // example onKeyUp
       $(".validate").on("keyup", function() {
           var result = validator.validate(validator);
           updateUi(result.validationResults, "form-group", "error_span");
       });
      
       </script>
      

    注意:updateUi(也可以在 JsFiddle 中找到)是一个自定义函数,用于更新错误范围以显示/隐藏。

    就是这样!

    我用 ajax 调用、select2、bootstrap 4 对其进行了测试,它可以工作。

    如果您发现可以改进的地方,请随时发表评论。 (我不是js高手,所以会发现错误。)

    编码愉快!

    【讨论】:

      【解决方案2】:

      我不知道为什么验证在上述方法中不起作用。我必须使用 jquery-unobtrusive-ajax。你可以参考这里https://dotnetthoughts.net/jquery-unobtrusive-ajax-helpers-in-aspnet-core/

      Validate Pop Up Modal using Ajax.Beginform 教程在这里 https://qawithexperts.com/article/asp.net/validate-pop-up-modal-using-ajaxbeginform-in-c-mvc/52

      【讨论】:

        【解决方案3】:

        您可以通过将 jquery-validatejquery-validation-unobtrusive 脚本与您通过模态调用的视图链接来修复它。

        您需要这样做,因为任何充当局部视图的视图都无法访问布局视图上的脚本或脚本标签。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-02-18
          • 1970-01-01
          • 2014-02-24
          • 1970-01-01
          • 2019-01-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多