본문 바로가기
ASP.NET Core

ASP.NET Core] Model Validation Check

by Fastlane 2021. 12. 31.
728x90
반응형

Introduction to Model Validation

Form Data는 정확성을 위해 validation을 확인해야 한다. validation은 client side, server side에서 가능하다. 

 

Client-Side Validation

  • 사용자 경험 개선
  • client browser에서 실행하므로, 반응이 빠르다. 
  • validation을 위한 HTTP Request/response가 없다. 

Server-Side Validation

Client-Side Validation은 사용자 경험 측면에서는 낫지만, 100% 신뢰할 수는 없다.

  • 사용자 브라우저에서 자바스크립트가 실행되지 않을 수 있다. 
  • 악의적인 사용자가 data를 직접 보낼 수 있다. 
  • 자바스크립트에 오류가 있으면, invalid data를 보낼 수 있다. 

따라서, client side에서 validation을 실행했어도, server side에서도 validation check하는 것이 중요하다. 

 

How Model Validation works

Model binder는 값을 action parameter에 bind 하고, Model Validator를 사용하여 유효성 검사한다.

이러한 Validation은 모두 server side에서 실행된다. ASP.NET Core는 많은 built-in Validation attribute를 가지고 있다. 

Validation attribute는 DataAnnotations이라고도 하고, System.ComponentModel.DataAnnotation namespace에 있다. 

 

1. Model에 특성 클래스를 활용해서 필드 조건을 지정함. 

    public class Category
    {
        [Key]
        public int Id { get; set; }
        [Required]
        [StringLength(maximumLength: 25, MinimumLength = 10, ErrorMessage = "Length must be between 10 to 25")]
        public string Name { get; set; }
        [DisplayName("Display Order")]
        [Range(1,100,ErrorMessage ="Display Order must be between 1 and 100 only!!")]
        public int DisplayOrder { get; set; }
        public DateTime CreatedDatetime { get; set; } = DateTime.Now;   
        [CreditCard(ErrorMessage ="Please enter a valid card No")]
        public string creditCard { get; set; }
        [Required(AllowEmptyStrings =false,ErrorMessage ="Please enter a valid password")]
        public string NewPassword { get; set; }
        [Compare(otherProperty:"NewPassword", ErrorMessage ="New & confirm password does not match")]
        public string ConfirmPassword { get; set; }
        [EmailAddress(ErrorMessage ="Please enter a valid email")]
        public string EmailID {get;set;}
        [RegularExpression(pattern: "^Mr\\..*|^Mrs\\..*|^Ms\\..*|^Miss\\..*", ErrorMessage ="Name must start with Mr./Mrs./Ms./Miss.")]
        public string FullName { get; set; }
        [Url(ErrorMessage ="Please enter a valid URL")]
        public string Url { get; set; }
    }

Required : 데이터 필드 필수값 지정

Range : 데이터 필드값에 대한 숫자 범위 제약조건 지정

CreditCard : 

이외 특성들은 아래 링크에서 확인 가능

https://docs.microsoft.com/ko-kr/dotnet/api/system.componentmodel.dataannotations?view=net-6.0 

 

System.ComponentModel.DataAnnotations 네임스페이스

ASP.NET MVC 및 ASP.NET 데이터 컨트롤의 메타데이터를 정의하는 데 사용되는 특성 클래스를 제공합니다. Provides attribute classes that are used to define metadata for ASP.NET MVC and ASP.NET data controls.

docs.microsoft.com

2. ModelState.IsValid 함수 사용

        //POST
        [HttpPost]
        [ValidateAntiForgeryToken] //Cross Site Request Forgery Attack을 방지한다.
        public IActionResult Create(Category obj)
        {
            if (obj.Name == obj.DisplayOrder.ToString())
            {
                //custom error message 설정
                //ModelState.AddModelError("CustomError", "TheDisplayOrder cannot exactly match the Name.");
                ModelState.AddModelError("name", "TheDisplayOrder cannot exactly match the Name.");
            }

            if (ModelState.IsValid) {

                _db.Categories.Add(obj);
                _db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(obj);
        }

ModelState.AddModelError()함수를 사용하여 CustomError도 추가 가능함. 

 

ModelState properties

Property Type Remarks
Keys KeyEnumerable Gets the key sequence. The collection of model properties' names. Keys Property gives you Access to state of individual model properties
Values ValueEnumerable The model properties' values Get the value sequence.
MaxAllowedErrors   Gets or sets the maximum allowed model state errors in this instance of ModelStateDictionary. Defaults to 200.
HasReachedMaxErrors bool Gets a value indicating whether or not the maximum number of errors have been recorded.
IsValid bool Whether or not the model is valid
Item ModelStateEntry Access to individual model properties' state
Count Int The count of model properties
ErrorCount int The number of errors that are added to this instance of ModelStateDictionary via AddModelError or TryAddModelError.

ModelState properties

  • AddModelError
  • Clear
  • ClearValidationState
  • GetFieldValidationState
  • GetValidationState
  • TryAddModelError
foreach (var modelStateKey in ModelState.Keys)
{
    var modelStateVal = ModelState[modelStateKey];
    foreach (var error in modelStateVal.Errors)
    {
        var key = modelStateKey;
        var errorMessage = error.ErrorMessage;
    }
}
if (ModelState.IsValid) { 
    If (someService.IsProductExists(model)) { 
        ModelState.AddModelError("", “Product already exists”); 
        return View(model); 
    } else { 
        return View(model); 
    } 
}

3. cshtml에 ValidationMessageTagHelper 추가 

@model Category

<form method="post">
    <div class="border p-3 mt-4">
        <div class="row pb-2">
            <h2 class="text-primary">Create Category</h2>
            <hr />
        </div>
        <div asp-validation-summary="All"></div>
        <div class="mb-3">
            <label asp-for="Name"></label>
            <input asp-for="Name" class="form-control"/>
            <span asp-validation-for="Name" class="text-danger"></span>
        </div>
        <div class="mb-3">
            <label asp-for="DisplayOrder"></label>
            <input asp-for="DisplayOrder" class="form-control"/>
            <span asp-validation-for="DisplayOrder" class="text-danger"></span>
        </div>
        <button type="submit" class="btn btn-primary" style="width:150px;">Create</button>
        <a asp-controller="Category" asp-action="Index" class="btn btn-secondary" style="width:150px">
            Back to List
        </a>
    </div>
</form>

<!-- client side validation -->
@section Scripts{    
    <partial name="_ValidationScriptsPartial" />
}

Model Validation Check를 Front에서 할 수 있도록 Script 추가 

_ValidationScriptsPartial.cshtml

<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

js파일 추가하면 페이지 reload 되지 않음. 

 

728x90
반응형

댓글