asp.net core自定义模型验证——前端验证

2023-10-19 19:26:10 浏览数 (1)

转载请注明出处:http://www.cnblogs.com/zhiyong-ITNote/

官方网站:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/models/validation?view=aspnetcore-2.1

首先派生自ValidationAttribute以及IClientModelValidator:

代码语言:javascript复制
public class ClassicMovieAttribute : ValidationAttribute, IClientModelValidator
    {
        private int _year;

        public ClassicMovieAttribute(int Year)
        {
            _year = Year;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            Movie movie = (Movie)validationContext.ObjectInstance;

            if (movie.Genre == Genre.Classic && movie.ReleaseDate.Year > _year)
            {
                return new ValidationResult(GetErrorMessage());
            }

            return ValidationResult.Success;
        }

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

        private string GetErrorMessage()
        {
            return $"Classic movies must have a release year earlier than {_year}.";
        }
    }

创建两个类:

代码语言:javascript复制
创建两个类:
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; }
}

public enum Genre
{
    Classic,
    PostClassic,
    Modern,
    PostModern,
    Contemporary,
}

视图方面:

代码语言:javascript复制
<form asp-action="Create">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="Title" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="ReleaseDate" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="ReleaseDate" class="form-control" />
                <span asp-validation-for="ReleaseDate" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="Description" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Description" class="form-control" />
                <span asp-validation-for="Description" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="Price" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Price" class="form-control" />
                <span asp-validation-for="Price" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="Genre" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <select asp-for="Genre" asp-items="@(Html.GetEnumSelectList<Genre>())" class="form-control"></select>
                <span asp-validation-for="Genre" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <div class="checkbox">
                    <input asp-for="Preorder" />
                    <label asp-for="Preorder"></label>
                </div>
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
</form>

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

    <script type="text/javascript">
     $(function () {
         $.validator.addMethod('classicmovie',
             function (value, element, params) {
                 // Get element value. Classic genre has value '0'.
                 var genre = $(params[0]).val(),
                     year = params[1],
                     date = new Date(value);
                 if (genre && genre.length > 0 && genre[0] === '0') {
                     // Since this is a classic movie, invalid if release date is after given year.
                     return date.getFullYear() <= year;
                 }

                 return true;
             });

         $.validator.unobtrusive.adapters.add('classicmovie',
             ['year'],
             function (options) {
                 var element = $(options.form).find('select#Genre')[0];
                 options.rules['classicmovie'] = [element, parseInt(options.params['year'])];
                 options.messages['classicmovie'] = options.message;
             });
     });
    </script>
}

然后创建一个Action:
public IActionResult Index(Movie movie)
{
    if(ModelState.isValid)
    {    
        return Content("dsadas");
    }
    return View();
}

然后创建一个Action:

代码语言:javascript复制
public IActionResult Index(Movie movie)
{
if(ModelState.isValid)
{    
return Content("dsadas");
}
return View();
}

我们可以在qq浏览器中的查看页面源代码,会给我们生成:

代码语言:javascript复制
<input class="form-control" type="datetime"
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="" />

也就是说,浏览器已经给我们解析好了,这样我们就可以一次比较,前后端验证。当然我们也可以使用bootstrapValidator验证。

0 人点赞