<sup id="sjju3"><noscript id="sjju3"></noscript></sup>
    <big id="sjju3"></big>

  • <blockquote id="sjju3"></blockquote>
    <blockquote id="sjju3"></blockquote>

      <td id="sjju3"></td>

      <big id="sjju3"></big>
        <code id="sjju3"><strong id="sjju3"><dl id="sjju3"></dl></strong></code>
      1. asp.net core系列之模型绑定和验证方法

         更新时间:2019年03月20日 14:16:50   投稿:zx   我要评论

        这篇文章主要介绍了asp.net core系列之模型绑定和验证方法,文?#22411;?#36807;示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

        一. 模型绑定

        ASP.NET Core MVC 中的模型绑定,是将 HTTP 请求中的数据映射到 action方法参数。   这些参数可能是简单类型的参数,如字符串、整数或浮点数,也可能是复杂类型的参数。  当 MVC 收到 HTTP 请求时,它会将此请求路由定位到控制器的指定 action方法。默?#19979;?#30001;模板为   {controller=Home}/{action=Index}/{id?}

        //例如:请求URL
        http://contoso.com/movies/edit/2
          
        //映射到movies/edit/2
        public IActionResult Edit(int? id)

        上面Url请求对应movies控制器下的Edit方法,该方法接受名为 id 的可选参数。MVC会将Edit中的id参数绑定到路由值中 具有相同名称 的值。 URL 路由中的字符串不区分大小?#30784;?/p>

        上面示例绑定的参数是简单类型,如果参数是一个类,例如 Movie 类型,该类包含简单和复杂类型作为属性,MVC的模型绑定仍然可以很好地处理它。它使用反射和递归来遍历寻找匹配的复杂类型的属性(如:Collection、Dictionary)。

        如果模型绑定失败,MVC 不会引发错误,参数值会是null。 如果HTTP 请求中的数据是用户输入的值,在action中应使用 ModelState.IsValid 属性检查,不需要手动去检查。

        注意:若要实现模型绑定,该类必须具有要绑定的公共默认构造函数和公共可?#35789;?#24615;。 发生模型绑定时,在使用公共默认构造函数对类进行实例化后才可设置属性。

        模型绑定完成后,将发生模型验证。 对于绝大多数开发方案,默认模型绑定效果极?#36873;?#36824;可以扩展,如果有特殊需求,则可自定义内置行为包括:模型绑定特性、全局自定义模型绑定和验证、绑定请求正文中的带格式数据(JSON、XML 和许多其他格式)、还有高级篇中自定义模型绑定。这里不在说明,请查看文档。

        二.模型验证

        在将数据存储到数据库之前,应用程序必须先验证数据。在 MVC 中,验证发生在客户端和服务器上。

        2.1 验证属性

        验证属性是模型验证的一种方法, 概念上类似于对数据库表中字段的验证, 验证属性在属性级别指定,下面是一个示例:

        public class Movie
        {
          public int Id { get; set; }
        
          [Required]
          [StringLength(100)]
          public string Title { get; set; }
        
          [ClassicMovie(1960)]
          [DataType(DataType.Date)]
          public DateTime ReleaseDate { get; set; }
        
          [Required]
          [StringLength(1000)]
          public string Description { get; set; }
        
          [Range(0, 999.99)]
          public decimal Price { get; set; }
        
          [Required]
          public Genre Genre { get; set; }
        
          public bool Preorder { get; set; }
        }

        常用的内置验证属性包括: [ CreditCard] 信用卡格式、 [Compare]匹配两个属性、 [ EmailAddress] 邮件格式、 [ Phone] 电话格式、 [Range] 给定?#27573;?#20869;、 [RegularExpression] 正则表达式、 [Required]必须属性值、 [StringLength] 最大长度、 [Url] URL格式,还可以包括自定义验证属性(例如 ClassicMovie )。 所有的内置验证属性 参考官网

        2.2 自定义验证

        上面的验证属性适用于大多数验证需求。 但是,某些验证规则特定于你的业务。在 MVC 中创建自定义验证属性很简单。只需从 ValidationAttribute 继承并重写  IsValid 方法。  IsValid 方法采用两个参数,第一个是名为 value 的对象,第二个是名为 validationContext 的  ValidationContext 对象。 Value 引用自定义验证程序要验证的字段中的实际值。

        /// <summary>
          /// 自定义验证
          /// </summary>
          public class ClassicMovieAttribute : ValidationAttribute
          {
            private int _year;
        
            /// <summary>
            /// 验证规则值
            /// </summary>
            /// <param name="year"></param>
            public ClassicMovieAttribute(int year)
            {
              _year = year;
            }
        
            protected override ValidationResult IsValid(object value, ValidationContext validationContext)
            {
              Movie movie = (Movie)validationContext.ObjectInstance;
        
              //用户不能将 1960 年以后发行的电影的流派设置为 Classic
              if (movie.Genre == "Classic" && movie.ReleaseDate.Year > _year)
              {
                return new ValidationResult(GetErrorMessage());
              }
        
              return ValidationResult.Success;
            }
        
            private string GetErrorMessage()
            {
              return $"Classic movies must have a release year earlier than {_year}.";
            }
          }

        运行程序,ReleaseDate是1989年,Genre是Classic,点击Save,验证是在服务端进行,显示错误消息,没有经过前端js验证,如下所示:

        2.3 客户端js验证介绍

        jQuery 非介入式验证脚本是一个自定义微软前端库,建立在流行的 jQuery Validate 插件。客户端验证原理是: MVC 的标?#21069;?#21161;程序和 HTML 帮助程序则能够使用模型属性中的验证特性和类型元数据,呈?#20013;?#35201;验证的表单元素中的 HTML 5 data- 属性。MVC 为内置模型属性和自定义模型属性生成 data- 属性。然后,jQuery 非介入式验证分析  data- 属性并将逻辑传递给 jQuery Validate,从而将服务器端验证逻辑有效地“复制”到客户端。 可以使用相关标?#21069;?#21161;程序在客户端上显示验证错误。

        下面示例表单中,asp- 标?#21069;?#21161;程序代码如下:

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

        标?#21069;?#21161;程序将生成以下source html。请注意,HTML 输出中的 data- 属?#26434;?nbsp; ReleaseDate 属性的验证特性相对应。下面的  data-val-required 属性包含在用户未填写发行日期字段时将显示的错误消息。jQuery 非介入式验证将此值传递给 jQuery Validate required() 方法,该方法随后在随附的 <span> 元素中显示该错误消息。

        <form action="/Movies/Create" method="post">
          <div class="form-horizontal">
            <h4>Movie</h4>
            <div class="text-danger"></div>
            <div class="form-group">
              <label class="col-md-2 control-label" for="ReleaseDate">ReleaseDate</label>
              <div class="col-md-10">
                <input class="form-control" type="datetime"
                data-val="true" data-val-required="The ReleaseDate field is required."
                id="ReleaseDate" name="ReleaseDate" value="" />
                <span class="text-danger field-validation-valid"
                data-valmsg-for="ReleaseDate" data-valmsg-replace="true"></span>
              </div>
            </div>
          </div>
        </form>

        2.4 动态表单添加验证

        在创建动态表单后,需要立即对其进行分析。 例如,下面的代码展示如何对通过 AJAX 添加的表单设置客户端验证。

        $.get({
          url: "https://url/that/returns/a/form",
          dataType: "html",
          error: function(jqXHR, textStatus, errorThrown) {
            alert(textStatus + ": Couldn't add form. " + errorThrown);
          },
          success: function(newFormHTML) {
            //添加表单newFormHTML
            var container = document.getElementById("form-container");
            container.insertAdjacentHTML("beforeend", newFormHTML);
            //验证第一个表单
            var forms = container.getElementsByTagName("form");
            var newForm = forms[forms.length - 1];
            //分析表单的 data- 属性
            $.validator.unobtrusive.parse(newForm);
          }
        })

        $.validator.unobtrusive.parse() 方法分析该选择器内表单的  data- 属性。当用户填写表单中的属性值提交时, 这些属性的值传递到 jQuery Validate 插件中,以便表单展示所需的客户端验证规则。

        下面用一个简单示例来说明:

        (1)  创建dynamic-form-validate.js文件,模拟动态生成表单,以及点击(#idbtn)按钮时验证:

        var newFormHTML = "<form action=\"create\" method=\"post\">";
        newFormHTML += "<div class=\"form-group\">";
        newFormHTML += "<label asp-for=\"Title\" class=\"control- label\"></label>";
        newFormHTML += "<input type=\"text\" data-val=\"true\" data-val-required=\"The Title field is required.\" id = \"Title\" name= \"Title\">";
        newFormHTML += "<span class=\"text- danger field- validation - valid\" data-valmsg-for=\"Title\" data-valmsg-replace=\"true\"></span>";
        newFormHTML += "</div>";
        newFormHTML += "<div class=\"form-group\" >";
        newFormHTML += "<input type=\"submit\" value=\"Save\" class=\"btn btn-primary\" />";
        newFormHTML += "</div >";
        newFormHTML += "</form>";
        
        $("#idbtn").click(function () {
          var container = document.getElementById("form-container");
          container.insertAdjacentHTML("beforeend", newFormHTML);
        
          var forms = container.getElementsByTagName("form");
          var newForm = forms[forms.length - 1];
          //分析表单的 data- 属性
          $.validator.unobtrusive.parse(newForm);
        });

        (2) 新建create页

        @model StudyMVCDemo.Models.Movie
        @{
          ViewData["Title"] = "Create";
        }
        <h1>Create</h1>
        
        <div class="row">
          <input value="动态加载表单" type="button" id="idbtn" />
          <div id="form-container" class="col-md-4">
        
          </div>
        </div>
        <div>
          <a asp-action="Index">Back to List</a>
        </div>
        @section Scripts {
          @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
          <script src="~/js/dynamic-form-validate.js"></script>
        }

        运行程序,点击"动态加载表单" 调用js将html表单添加到form-container元素容器中,点击save提示该字段不能为空,效果如下所示:

        2.5 动态控件添加验证

        当向表单动态添加控件(比如:  <input/> 和  <select/> )时,需要更新表单?#31995;?#39564;证规则。做法是应当先删除现有的验证数据,然后重新分析整个表单,如下js代码所示:

        $.get({
          url: "https://url/that/returns/a/control",
          dataType: "html",
          error: function(jqXHR, textStatus, errorThrown) {
            alert(textStatus + ": Couldn't add control. " + errorThrown);
          },
          success: function(newInputHTML) {
             //向表单动态添加Input控件
            var form = document.getElementById("my-form");
            form.insertAdjacentHTML("beforeend", newInputHTML);
             //移除现有的验证
            $(form).removeData("validator")  // Added by jQuery Validate
                .removeData("unobtrusiveValidation");  // Added by jQuery Unobtrusive Validation
             //重新分析整个表单
            $.validator.unobtrusive.parse(form);
          }
        })

        2.6  IClientModelValidator

        在上面2.2自定义验证中,继承了ValidationAttribute进行服务端验证,还可以结合实现IClientModelValidator接口实现客户端验证,?#23186;?#21475;用来控制要添加哪些 data- 属性。实现接口如下所示:

        /// <summary>
          /// 自定义验证
          /// </summary>
          public class ClassicMovieAttribute : ValidationAttribute,IClientModelValidator
          {
            private int _year;
        
            /// <summary>
            /// 年份参考值
            /// </summary>
            /// <param name="year"></param>
            public ClassicMovieAttribute(int year)
            {
              _year = year;
            }
        
            protected override ValidationResult IsValid(object value, ValidationContext validationContext)
            {
              Movie movie = (Movie)validationContext.ObjectInstance;
        
              //用户不能将 1960 年以后发行的电影的流派设置为 Classic
              if (movie.Genre == "Classic" && movie.ReleaseDate.Year > _year)
              {
                return new ValidationResult(GetErrorMessage());
              }
        
              return ValidationResult.Success;
            }
        
            private string GetErrorMessage()
            {
              return $"Classic movies must have a release year earlier than {_year}.";
            }
        
            public void AddValidation(ClientModelValidationContext context)
            {
              if (context == null)
              {
                throw new ArgumentNullException(nameof(context));
              }
        
              MergeAttribute(context.Attributes, "data-val", "true");
              MergeAttribute(context.Attributes, "data-val-classicmovie", GetErrorMessage());
        
              var year = _year.ToString(CultureInfo.InvariantCulture);
              MergeAttribute(context.Attributes, "data-val-classicmovie-year", year);
            }
        
            private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
            {
              if (attributes.ContainsKey(key))
              {
                return false;
              }
        
              attributes.Add(key, value);
              return true;
            }
          }

        生成的源html代码如下所示:

        <input class="form-control" type="date" 
        data-val="true" 
        data-val-classicmovie="Classic movies must have a release year earlier than 1960."
        data-val-classicmovie-year="1960" 
        data-val-required="The ReleaseDate field is required." 
        id="ReleaseDate" name="ReleaseDate" value="1989-02-12">

        在上面虽然实现了IClientModelValidator接口,但jQuery不了解规则或消息,还需要自定义 classicmovie 客户端验证方法,添加到jQuery  validator 对象。脚本如下所示:

        //添加验证方法
        $.validator.addMethod('classicmovie',function (value, element, params) {
             //value ,是当前验证的元素的值。
             //element 元素本身。
             //params 是传入的参数(options.rules)
            var genre = $("#form1").find("#Genre").val(),
              year = params[0],
              date = new Date(value);
            if (genre.length > 0 && genre === 'Classic') {
              // Since this is a classic movie, invalid if release date is after given year.
              return date.getFullYear() <= year;
            }
            return true;
          });
        
        //注册一个适配器,参数1是适配器名称,参数2是验证规则的名称
        $.validator.unobtrusive.adapters.add('classicmovie',['year'],function (options) {
            //适配器规则绑定到jquery validation上面
            options.rules['classicmovie'] = [parseInt(options.params['year'])];
            options.messages['classicmovie'] = options.message;
          });

        运行程序,ReleaseDate是1989年,Genre是Classic,点击Save,客户端验证返回false,提示错误信息,如下所示:

        参考文献

        模型绑定

        模型验证

        以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

        相关文章

      2. asp.net实现DataList与Repeater嵌套绑定的方法

        asp.net实现DataList与Repeater嵌套绑定的方法

        这篇文章主要介绍了asp.net实现DataList与Repeater嵌套绑定的方法,结合实例形式分析了DataList与Repeater的步骤与相关实现技巧,需要的朋友可以参考下
        2016-04-04
      3. asp.net HTML文件上传标签

        asp.net HTML文件上传标签

        需要在要目录下新建两个目录:upfile和upimg 添加一个FileUpload控件.一个Button.一个Image.一个Label
        2008-12-12
      4. 水晶报表?#35745;?#19981;显示两种问题分析及解决方法

        水晶报表?#35745;?#19981;显示两种问题分析及解决方法

        水晶报表布置后里面的?#35745;?#19981;显示的情况,分两种:一是:水晶报表工具栏?#31995;耐计?#19981;显示;二是:水晶报表中的的?#35745;?#23545;象不显示,接下来将分别介绍解决方法,?#34892;?#36259;的朋友可以了解下啊
        2013-01-01
      5. ASP.NET Core2?#21015;碔nfluxDB时序数据库的方法教程

        ASP.NET Core2?#21015;碔nfluxDB时序数据库的方法教程

        Influxdb是一个开源的分布式时序、时间和指标数据库,使用go语言编写,无需外部依赖,下面这篇文章主要给大家介绍了关于ASP.NET Core2?#21015;碔nfluxDB时序数据库的相关资?#24076;?#38656;要的朋友可以参考下
        2018-11-11
      6. DataSet.Tables[].Rows[][]的用法详细解析

        DataSet.Tables[].Rows[][]的用法详细解析

        以下是对DataSet.Tables[].Rows[][]的用法进行了详细的分析介绍,需要的朋友可以过来参考下
        2013-09-09
      7. 详解最好的.NET开源免费ZIP库DotNetZip(.NET组件介绍之三)

        详解最好的.NET开源免费ZIP库DotNetZip(.NET组件介绍之三)

        本篇文章主要介绍了.NET开源免费ZIP库DotNetZip组件的介绍,可以实现对文件的压缩和解压,有兴趣的朋友可以了解一下。
        2016-12-12
      8. ASP.NET存储过程实现分页效果(三层架构)

        ASP.NET存储过程实现分页效果(三层架构)

        这篇文章主要为大家详细介绍了ASP.NET存储过程实现分?#24120;?#21033;用三层架构实现分页效果,有参?#25216;?#20540;的一篇文章,?#34892;?#36259;的小伙伴们可以参?#23478;?#19979;
        2016-05-05
      9. JavaScript验证用户输入的是字符或数字及ASCII Chart应用

        JavaScript验证用户输入的是字符或数字及ASCII Chart应用

        我们可以根据onkeydown事件的event.keyCode?#35789;茿SCII Chart来判断字符或数?#20540;?本文提供了相关键盘key对应的ASCII码,以供用户使用是参?#25216;?#20351;用onpaste事件只能输入字符和数字防止?#31243;?#31561;?#27169;行?#36259;的朋友可以了解下
        2013-01-01
      10. 最新评论

        常用在线小工具

        2018白小姐一肖中特马
        <sup id="sjju3"><noscript id="sjju3"></noscript></sup>
        <big id="sjju3"></big>

      11. <blockquote id="sjju3"></blockquote>
        <blockquote id="sjju3"></blockquote>

          <td id="sjju3"></td>

          <big id="sjju3"></big>
            <code id="sjju3"><strong id="sjju3"><dl id="sjju3"></dl></strong></code>
          1. <sup id="sjju3"><noscript id="sjju3"></noscript></sup>
            <big id="sjju3"></big>

          2. <blockquote id="sjju3"></blockquote>
            <blockquote id="sjju3"></blockquote>

              <td id="sjju3"></td>

              <big id="sjju3"></big>
                <code id="sjju3"><strong id="sjju3"><dl id="sjju3"></dl></strong></code>
              1. 组三的位置怎么选 福利彩26选5好彩3 澳门赌场娱乐城推币机 福彩3d012路遗漏分析 牌九大小牌 彩票投注张公岭 北单网 全运会乒乓球 天天酷跑玩法技巧 黑龙赌王双胆历史记录 山西11选5走势图遗漏top10 彩票出售软件 闲和庄娱乐城投注网 一码中特死公式 澳洲幸运5计划软件手机版式