TOC

This article is currently in the process of being translated into Vietnamese (~50% done).

Models:

Model Validation

In the previous article, we talked about DataAnnotations and how they can enrich your Models to work even tighter together with your Views. However, a lot of the available DataAnnotations are actually directly related to the validation mechanisms found in the ASP.NET MVC framework. They will allow you to enforce various kinds of rules for your properties, which will be used in your Views and in your Controllers, where you will be able to check whether a certain Model is valid in its current state or not (e.g. after a FORM submission).

Adding basic validation

Just like we saw in the previous article, validation rules can be applied to properties through the use of DataAnnotations. There are several types available, but for now, we'll add just a couple of them to the WebUser class previously introduced:

public class WebUser  
{  
    [Required]
    [StringLength(25)]
    public string FirstName { get; set; }

    [Required]
    [StringLength(50, MinimumLength = 3)]
    public string LastName { get; set; }

    [Required]
    [EmailAddress]
    public string MailAddress { get; set; }
}

Có ba thuộc tính đã được thêm vào DataAnnotation, để kiểm tra dữ liệu. Đầu tiên, toàn bộ thuộc tính đều là [Required], tức là không chấp nhận giá trị rỗng. Ngoài ra là thuộc tính [StringLength] xác định độ dài lớn nhất và có cả độ dài nhỏ nhất của chuỗi. Thuộc tính cuối cùng là [EmailAddress] đảm bảo giá trị có dạng địa chỉ email.

Chúng ta dùng ModelBiding để tạo trường cho thuộc tính:

@model HelloMVCWorld.Models.WebUser
@using(var form = Html.BeginForm())
{
    <div>
@Html.LabelFor(m => m.FirstName)
@Html.TextBoxFor(m => m.FirstName)
    </div>

    <div>
@Html.LabelFor(m => m.LastName)
@Html.TextBoxFor(m => m.LastName)
    </div>

    <div>
@Html.LabelFor(m => m.MailAddress)
@Html.TextBoxFor(m => m.MailAddress)
    </div>

    <input type="submit" value="Submit" />
}

Giờ chúng ta chỉ cần một Controller để xử lý View cũng như xử lý POST sau khi FORM được gửi đi:

public class ValidationController : Controller
{
    [HttpGet]
    public IActionResult SimpleValidation()
    {
return View();
    }

    [HttpPost]
    public IActionResult SimpleValidation(WebUser webUser)
    {
if(ModelState.IsValid)
    return Content("Thank you!");
else
    return Content("Model could not be validated!");
    }

}

Trong phần này, với POST chúng ta kiểm tra IsValid của ModelState. Tùy vào dữ liệu chúng ta đưa lên FORM mà đúng hay sai theo quy định mà ta đã thiết lập trong Model (WebUser). Như vậy bạn có thể tránh lưu Model sai.

Displaying validation errors

Trong ví dụ trên, chúng ta có thể thấy Model có thể đúng hoặc sai dựa vào DataAnnotation mà ta áp dụng cho Model. Nhưng hay hơn nữa chúng ta có thể báo cho người dùng biết lỗi ở đâu để họ có thể sửa một cách dễ dàng.

Chúng ta cần mở rộng FORM để có thể hiển thị thông báo lỗi cho người dùng. Chúng ta có thể dùng phương thức helper khác của đối tượng Html: phương thức ValidationMessageFor(). Chỉ đơn giản là xuất ra thông báo lỗi liên quan tới trường dữ liệu nếu có như sau:

@model HelloMVCWorld.Models.WebUser
@using(var form = Html.BeginForm())
{
    <div>
@Html.LabelFor(m => m.FirstName)
@Html.TextBoxFor(m => m.FirstName)
@Html.ValidationMessageFor(m => m.FirstName)
    </div>

    <div>
@Html.LabelFor(m => m.LastName)
@Html.TextBoxFor(m => m.LastName)
@Html.ValidationMessageFor(m => m.LastName)
    </div>

    <div>
@Html.LabelFor(m => m.MailAddress)
@Html.TextBoxFor(m => m.MailAddress)
@Html.ValidationMessageFor(m => m.MailAddress)
    </div>

    <input type="submit" value="Submit" />
}

Chúng ta cũng cần đảm bảo rằng một khi FORM được gửi đi, và nếu có lỗi thì chúng ta gửi lại FORM cho người dùng để họ có thể thấy và sửa lỗi. Chúng ta thực hiện trong Controller bằng cách trả về View và trạng thái của Model hiện tại nếu có lỗi:

[HttpPost]
public IActionResult SimpleValidation(WebUser webUser)
{
    if(ModelState.IsValid)
return Content("Thank you!");
    else
return View(webUser);
}

With that in place, try submitting the FORM with empty fields. You should be immediately returned to the FORM, but with validation messages next to each of the fields, thanks to the [Required] attribute:

Nếu bạn gửi FORM với giá trị không đúng với chiều dài chuỗi thì bạn sẽ nhận được thông báo lỗi. Chảng hạn bạn gửi FORM với LastName quá dài hoặc quá ngắn thì bạn sẽ nhận được thông báo lỗi sau:

The field LastName must be a string with a minimum length of 3 and a maximum length of 50.

Nhưng nếu bạn muốn thông báo lỗi hiển thị khác đi? Bạn có thể làm như sau:

public class WebUser  
{  
    [Required(ErrorMessage = "You must enter a value for the First Name field!")]  
    [StringLength(25, ErrorMessage = "The First Name must be no longer than 25 characters!")]  
    public string FirstName { get; set; }  

    [Required(ErrorMessage = "You must enter a value for the Last Name field!")]  
    [StringLength(50, MinimumLength = 3, ErrorMessage = "The Last Name must be between 3 and 50 characters long!")]  
    public string LastName { get; set; }  

    [Required(ErrorMessage = "You must enter a value for the Mail Address field!")]  
    [EmailAddress(ErrorMessage = "Please enter a valid e-mail address!")]  
    public string MailAddress { get; set; }  
}

So as you can see, it's really easy to customize the error messages!

Displaying a validation summary

An individual error message for each input field can be really useful, especially if you have a large FORM. However, for smaller forms, like the one in our example, it might be more useful to simply display a summary of the validation errors, either above or below all the fields. That's easily accomplished, thanks to the ValidationSummary() method found on the Html helper object:

@model HelloMVCWorld.Models.WebUser
@using(var form = Html.BeginForm())
{
    @Html.ValidationSummary()
   
    <div>
@Html.LabelFor(m => m.FirstName)
@Html.TextBoxFor(m => m.FirstName)        
    </div>

    <div>
@Html.LabelFor(m => m.LastName)
@Html.TextBoxFor(m => m.LastName)        
    </div>

    <div>
@Html.LabelFor(m => m.MailAddress)
@Html.TextBoxFor(m => m.MailAddress)        
    </div>

    <input type="submit" value="Submit" />
}

Now, when the FORM is submitted and returned with validation errors, it will look like this instead:

Of course, you can combine the per-field validation message approach with a validation summary, if you feel like it.

Summary

Adding basic Model Validation is very easy and will help ensure that user-provided information matches the requirements you may have for the data. As mentioned, these are just some of the validation options available in the ASP.NET MVC framework. In the next article, we'll look into the rest of them!


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!