C# Cơ bản .NET Core §1) Cài đặt, chương trình C# đầu tiên §2) Biến, kiểu dữ liệu và nhập/xuất §3) Toán tử số học và gán §4) So sánh, logic và lệnh if, switch §5) Vòng lặp for, while §6) Phương thức - Method §7) Phương thức - Delegate §8) Lớp - Class §9) Kiểu vô danh và dynamic §10) Biểu thức lambda §11) Event §12) Hàm hủy - Quá tải toán tử - thành viên tĩnh - indexer §13) Lớp lồng nhau - namespace §14) null và nullable §15) Mảng §16) Chuỗi ký tự §17) Tính kế thừa §18) Tính đa hình - abstract - interface §19) Struct và Enum §20) Ngoại lệ Exeption §21) IDisposable - using §22) File cơ bản §23) FileStream §24) Generic §25) Collection - List §26) SortedList §27) Queue / Stack §28) Linkedlist §29) Dictionary - HashSet §30) Phương thức mở rộng §31) ObservableCollection §32) LINQ §33) (Multithreading) async - bất đồng bộ §34) Type §35) Attribute Annotation §36) DI Dependency Injection §37) (Multithreading) Parallel §38) (Networking) HttpClient §39) (Networking) HttpMessageHandler §40) (Networking) HttpListener §41) (Networking) Tcp TcpListenerr/TcpClient §42) (ADO.NET) SqlConnection §43) (ADO.NET) SqlCommand §44) (EF Core) Tổng quan §45) (EF Core) Tạo Model §46) (EF Core) Fluent API §47) (EF Core) Query §48) (EF Core) Scaffold §49) (EF Core) Migration §50) (ASP.NET CORE) Hello World! §51) (ASP.NET CORE) Middleware §52) (ASP.NET CORE) Map - Request - Response §53) (ASP.NET CORE) IServiceCollection - MapWhen §54) (ASP.NET CORE) Session - ISession §55) (ASP.NET CORE) Configuration §56) (ASP.NET CORE MVC) Controller - View
Lập trình C# (C Sharp)

Khái niệm về Annotation (Attribute)

Một chú thích (Annotation) tác động một thành phần nào đó của chương trình (lớp, phương thức, thuộc tính) nó là một phần của siêu dữ liệu (metadata - loại dữ liệu cung cấp thông tin về dữ liệu khác). Annotation giúp thêm thông tin vào lớp, phương thức, thuộc tính những đoạn code mở rộng. Tính năng này trong Java gọi là Annotation, trong C# gọi là Attribute.

Trong C# có định nghĩa sẵn vô số các Attribute, để sử dụng nó bạn chỉ cần viết tên Attribute trong dấu [] trước đối tượng áp dụng như lớp, phương thức, thuộc tính lớp (có tham số như hàm, nếu Attribute đó yêu cầu).

[AttributeName(param1, param2 ...)]

Ví dụ: trong C# có thuộc tính Obsolete, để đánh dấu một phương thức, lớp ... nào đó là lạc hậu.

using System;

namespace DataAnnotation
{
    public class MyClass {

        [Obsolete("Phương thức này lỗi thời, hãy  dùng phương thức Abc")]  // Đánh dấu phương thức Method1 lạc hậu
        public static void Method1() {
            Console.WriteLine("Phương thức chạy");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyClass.Method1();
        }
    }
}

Kết quả là khi soạn code, hay khi biên dịch sẽ có cảnh báo.

Tự tạo Attribute C#

Để tạo Attribute riêng khá đơn giản, bạn chỉ việc tạo một lớp kế thừ từ System.Attribute. Tuy nhiên để sử dụng được trước tiên cần thành thạo kỹ thuật Reflection trong C#. Ở mức độ đơn giản, hãy tìm hiểu và sử dụng Type tại Đọc thuộc tính lớp với Type . Giờ thử thực hành tạo một Attribute riêng đặt tên là MotaAttribute, thuộc tính này để bạn thêm thông tin mô tả nào đó (string) cho thành phần áp dụng (như lớp, thuộc tính, phương thức)

Attributes/MotaAttribute.cs
using System;
namespace DataAnnotation.Attributes
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Method)]
    public class MotaAttribute : Attribute // có thể đặt tên Mota thay cho MotaAttribute
    {
        public MotaAttribute(string v) => Description = v;

        public string Description {set; get;}
    }
}

Trong định nghĩa trên, AttributeUsage() là để thiết lập thuộc tính Mota áp dụng được cho những thành phần nào, như có AttributeTargets.Property nghĩa là được phép áp dụng cho các thuộc tính lớp.

Như vậy bạn đã tạo được một thuộc tính Mota, áp dụng cho đối tượng nào thì chỉ cần viết

[Mota("mô tả gì đó")]

Áp dụng Attribute Mota

using System;
using DataAnnotation.Attributes;

namespace DataAnnotation
{

    [Mota("Lớp biểu diễn người dùng")]                  // thêm Attribute cho lớp
    public class User
    {
        [Mota("Thuộc tính lưu tuổi")]                   // thêm Attribute cho thuộc tính lớp
        public int age {set; get;}

        [Mota("Phương thức này hiện thị age")]          // thêm Attribute cho phương thức
        public void ShowAge()
        {
        }
    }

class Program { static void Main(string[] args) { var a = new User(); // Đọc các Attribute của lớp foreach (Attribute attr in a.GetType().GetCustomAttributes(false)) { MotaAttribute mota = attr as MotaAttribute; if (mota != null) { Console.WriteLine($"{a.GetType().Name,10} : {mota.Description}"); } } // Đọc Attribute của từng thuộc tính lớp foreach (var thuoctinh in a.GetType().GetProperties()) { foreach (Attribute attr in thuoctinh.GetCustomAttributes(false)) { MotaAttribute mota = attr as MotaAttribute; if (mota != null) { Console.WriteLine($"{thuoctinh.Name,10} : {mota.Description}"); } } } // Đọc Attribute của phương thức foreach (var m in a.GetType().GetMethods()) { foreach (Attribute attr in m.GetCustomAttributes(false)) { MotaAttribute mota = attr as MotaAttribute; if (mota != null) { Console.WriteLine($"{m.Name,10} : {mota.Description}"); } } } } } }

Chú ý, các phương thức GetCustomAttributes() của Reflection sử dụng ở trên lấy Attribute được thêm vào. Chạy code trên, kết quả:

Data Annotation trong C#

Các Data Annotation trong C# định nghĩa trong namespace System.ComponentModel.DataAnnotations, có các loại gồm:

  • Các Attribute để kiểm tra dữ liệu (Validation Attribute)
  • Các Attribute hiện thị (Display Attribute), điều khiển dữ liệu trong lớp hiện thị thế nào trong UI
  • Modelling Attribute

Hãy thử xem một vài Attribute:

Required Dữ liệu phải được thiết lập (!=null)
[Required (ErrorMessage="{0} cần thiết lập")]
StringLength Thiết lập độ dài trường dữ liệu
[StringLength (20,MinimumLength=3, ErrorMessage="Phải dài 3 đến 20 ký tự")]
DataType Chỉ ra dữ liệu phải liên kết phù hợp với một kiểu nào đó
[DataType(DataType.Text)]
[DataType(DataType.PhoneNumber)]
[DataType(DataType.EmailAddress)]
/.. Date, DateTime, Html, ImageUrl, MultilineText, Password, Time, Url
Range Chỉ ra dữ liệu phải trong khoảng nào đó
[Range(18,99, ErrorMessage="Tuổi từ 18 đến 99")]
[Range(typeof(DateTime), "1/2/2004", "3/4/2004",
        ErrorMessage = "Value for {0} must be between {1} and {2}")]
Phone [Phone] dữ liệu phải là dạng số điện thoại
EmailAddress [EmailAddress] dữ liệu phải là dạng email

Ví dụ:

Model/User.cs
using System.ComponentModel.DataAnnotations;
namespace DataAnnotation.Model
{
    public class User
    {
        [Required (ErrorMessage="Employee {0} is required")]
        [StringLength (100,MinimumLength=3, ErrorMessage="Tên từ 3 đến  100 ký tự")]
        [DataType(DataType.Text)]
        public string Name { get; set; }

        [Range(18,99, ErrorMessage="Age should be between 18 and 99")]
        public int Age { get; set; }

        [DataType(DataType.PhoneNumber)]
        [Phone]
        public string PhoneNumber {set; get;}

        [DataType(DataType.EmailAddress)]
        [EmailAddress]
        public string Email { get; set; }

    }
}

Để kiểm tra các dữ liệu phù hợp thì dùng lớp ValidationContext, ví dụ:

using System;
using System.ComponentModel.DataAnnotations;
using DataAnnotation.Model;
using System.Collections.Generic;
using System.Linq;

namespace DataAnnotation
{
    class Program
    {

        static void Main(string[] args)
        {

            User user        = new User();
            user.Name        = "AF";
            user.Age         = 6;
            user.PhoneNumber = "1234as";
            user.Email       = "test@re";

            ValidationContext context       = new ValidationContext(user, null, null);
            List<ValidationResult> results  = new List<ValidationResult>();
            bool valid = Validator.TryValidateObject(user, context, results, true);

            if (!valid)
            {
                foreach (ValidationResult vr in results)
                {
                    Console.ForegroundColor = ConsoleColor.Blue;
                    Console.Write($"{vr.MemberNames.First(), 13}");
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine($"    {vr.ErrorMessage}");
                }
            }
        }
    }
}

Đăng ký theo dõi ủng hộ kênh