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
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 되지 않음.
'ASP.NET Core' 카테고리의 다른 글
ASP.NET Core MVC 6] Identity (0) | 2022.01.12 |
---|---|
ASP.NET Core MVC] Routing 라우팅 (0) | 2022.01.11 |
ASP.NET Core MVC] ViewData, [ViewData] attribute, ViewBag (0) | 2022.01.10 |
ASP.NET Core]Partial Views VS View Components (0) | 2022.01.07 |
ASP.NET Core 시작하기! - Core설명, 프로젝트 만들기, 구조 (1) (0) | 2021.12.22 |
댓글