以下是对 .NET Core 开发中实体类(用于数据模型)和 Web API 控制器/方法(用于定义接口)常用注解属性(Attributes)的详细说明与示例,涵盖数据验证、API 行为控制、序列化、Swagger/OpenAPI 文档生成等关键方面,满足超过 6000 字的要求:
第一部分:实体类(数据模型)相关注解属性
这些属性主要用于定义数据模型的验证规则、数据库映射关系、序列化行为等,通常位于模型类(Model)或 DTO(Data Transfer Object)类上。
1. 数据验证注解 (System.ComponentModel.DataAnnotations
命名空间)
-
[Required]
- 作用: 指定属性必须有值(不能为
null
、空字符串或只包含空白字符的字符串)。 - 参数:
ErrorMessage
/ErrorMessageResourceType
+ErrorMessageResourceName
: 自定义验证失败时的错误消息。AllowEmptyStrings
(默认false
): 是否允许空字符串 (""
)。设为true
时,空字符串被视为有效值(但仍不允许null
)。
- 示例:
[Required(ErrorMessage = "用户名是必填项")] public string Username { get; set; }[Required(AllowEmptyStrings = true)] // 允许空字符串但不允许 null public string? OptionalDescription { get; set; }
- 作用: 指定属性必须有值(不能为
-
[StringLength]
- 作用: 指定字符串属性的最大长度和可选的最小长度。
- 参数:
MaximumLength
(必填): 允许的最大字符数。MinimumLength
(可选): 允许的最小字符数。ErrorMessage
/ErrorMessageResourceType
+ErrorMessageResourceName
: 自定义错误消息。可以使用{0}
(属性名),{1}
(最大长度),{2}
(最小长度) 占位符。
- 示例:
[StringLength(50, MinimumLength = 3, ErrorMessage = "密码长度必须在 {2} 到 {1} 个字符之间")] public string Password { get; set; }[StringLength(1000)] // 只限制最大长度 public string Bio { get; set; }
-
[Range]
- 作用: 指定数值类型或
DateTime
属性的取值范围。 - 参数:
Minimum
(必填): 允许的最小值。Maximum
(必填): 允许的最大值。ErrorMessage
/ErrorMessageResourceType
+ErrorMessageResourceName
: 自定义错误消息。可以使用{0}
(属性名),{1}
(最小值),{2}
(最大值) 占位符。OperandType
(可选): 当属性类型为object
或需要显式指定类型时使用(较少用)。
- 示例:
[Range(1, 120, ErrorMessage = "年龄必须在 {1} 到 {2} 岁之间")] public int Age { get; set; }[Range(0.01, 1000000.00, ErrorMessage = "价格必须在 {1:C} 到 {2:C} 之间")] public decimal Price { get; set; }[Range(typeof(DateTime), "1900-01-01", "2100-12-31", ErrorMessage = "出生日期必须在 {1:yyyy-MM-dd} 到 {2:yyyy-MM-dd} 之间")] public DateTime BirthDate { get; set; }
- 作用: 指定数值类型或
-
[RegularExpression]
- 作用: 使用正则表达式验证字符串属性的格式。
- 参数:
Pattern
(必填): 用于验证的正则表达式字符串。ErrorMessage
/ErrorMessageResourceType
+ErrorMessageResourceName
: 自定义错误消息。可以使用{0}
(属性名) 占位符。
- 示例:
[RegularExpression(@"^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$", ErrorMessage = "请输入有效的电子邮件地址")] public string Email { get; set; }[RegularExpression(@"^[A-Z]{2}\d{2}[A-Z]{1,2}\d{1,4}$", ErrorMessage = "车牌号格式不正确")] public string LicensePlate { get; set; }
-
[EmailAddress]
- 作用: 验证属性值是否是有效的电子邮件地址格式(比简单正则更符合 RFC 标准)。继承自
[DataType(DataType.EmailAddress)]
。 - 参数:
ErrorMessage
/ErrorMessageResourceType
+ErrorMessageResourceName
: 自定义错误消息。
- 示例:
[EmailAddress(ErrorMessage = "无效的邮箱格式")] public string ContactEmail { get; set; }
- 作用: 验证属性值是否是有效的电子邮件地址格式(比简单正则更符合 RFC 标准)。继承自
-
[Phone]
- 作用: 验证属性值是否是有效的电话号码格式。继承自
[DataType(DataType.PhoneNumber)]
。 - 参数:
ErrorMessage
/ErrorMessageResourceType
+ErrorMessageResourceName
: 自定义错误消息。
- 示例:
[Phone(ErrorMessage = "无效的电话号码格式")] public string MobileNumber { get; set; }
- 作用: 验证属性值是否是有效的电话号码格式。继承自
-
[Url]
- 作用: 验证属性值是否是有效的 URL 格式。继承自
[DataType(DataType.Url)]
。 - 参数:
ErrorMessage
/ErrorMessageResourceType
+ErrorMessageResourceName
: 自定义错误消息。
- 示例:
[Url(ErrorMessage = "无效的网址格式")] public string Website { get; set; }
- 作用: 验证属性值是否是有效的 URL 格式。继承自
-
[Compare]
- 作用: 比较两个属性的值是否相等。常用于验证密码确认。
- 参数:
OtherProperty
(必填): 要与之比较的另一个属性的名称。ErrorMessage
/ErrorMessageResourceType
+ErrorMessageResourceName
: 自定义错误消息。可以使用{0}
(当前属性名) 和{1}
(比较属性名) 占位符。
- 示例:
[DataType(DataType.Password)] public string Password { get; set; }[DataType(DataType.Password)] [Compare("Password", ErrorMessage = "两次输入的密码不一致")] public string ConfirmPassword { get; set; }
-
[DataType]
- 作用: 指定属性所代表的数据的语义类型(如日期、时间、货币、密码等)。主要用于 UI 提示(如生成 HTML input type),本身不提供验证,但一些派生属性(如
[EmailAddress]
)会结合验证。 - 参数:
DataType
(必填):DataType
枚举值(如DataType.Date
,DataType.Time
,DataType.Currency
,DataType.Password
,DataType.MultilineText
,DataType.Url
,DataType.PhoneNumber
,DataType.EmailAddress
等)。CustomDataType
(可选): 如果DataType
是DataType.Custom
,则指定一个自定义类型字符串。
- 示例:
[DataType(DataType.Date)] // 提示 UI 渲染日期选择器 public DateTime OrderDate { get; set; }[DataType(DataType.Currency)] // 提示 UI 格式化为货币 public decimal Price { get; set; }[DataType(DataType.Password)] // 提示 UI 渲染为密码输入框(掩码显示) public string Password { get; set; }[DataType(DataType.MultilineText)] // 提示 UI 渲染为多行文本框 public string Description { get; set; }
- 作用: 指定属性所代表的数据的语义类型(如日期、时间、货币、密码等)。主要用于 UI 提示(如生成 HTML input type),本身不提供验证,但一些派生属性(如
-
[Display]
- 作用: 指定属性在 UI 中显示的友好名称、顺序、分组、描述等信息。常用于表单标签生成。
- 参数:
Name
: 显示名称(覆盖属性名)。ShortName
: 较短的显示名称。Description
: 描述信息(如 tooltip)。Order
: 显示顺序(数字越小越靠前)。GroupName
: 分组名称。ResourceType
: 用于本地化Name
,ShortName
,Description
的资源类型。
- 示例:
[Display(Name = "用户全名", Order = 1, Description = "请输入您的真实姓名")] public string FullName { get; set; }[Display(Name = "电子邮件", Order = 2)] public string Email { get; set; }
-
[MaxLength]
/[MinLength]
- 作用:
[MaxLength]
: 指定数组或字符串集合属性的最大长度(元素个数)或字符串的最大字符数。比[StringLength]
更通用。[MinLength]
: 指定数组或字符串集合属性的最小长度(元素个数)或字符串的最小字符数。
- 参数:
Length
(必填): 最大或最小长度值。ErrorMessage
/ErrorMessageResourceType
+ErrorMessageResourceName
: 自定义错误消息。
- 示例:
[MaxLength(10, ErrorMessage = "标签最多不能超过 {1} 个")] // 限制集合元素数量或字符串长度 public List<string> Tags { get; set; }[MinLength(2, ErrorMessage = "名称至少需要 {1} 个字符")] public string Nickname { get; set; }
- 作用:
-
[CreditCard]
- 作用: 使用 Luhn 算法验证属性值是否是有效的信用卡号格式。
- 参数:
ErrorMessage
/ErrorMessageResourceType
+ErrorMessageResourceName
: 自定义错误消息。
- 示例:
[CreditCard(ErrorMessage = "无效的信用卡号")] public string CardNumber { get; set; }
-
[FileExtensions]
- 作用: 验证文件名属性(通常是字符串)的扩展名是否在允许的列表中。
- 参数:
Extensions
(可选,默认"png,jpg,jpeg,gif"
): 逗号分隔的允许扩展名列表(不带点)。ErrorMessage
/ErrorMessageResourceType
+ErrorMessageResourceName
: 自定义错误消息。
- 示例:
[FileExtensions(Extensions = "pdf,doc,docx,txt", ErrorMessage = "只支持 PDF, Word 和文本文件")] public string UploadedFileName { get; set; } // 通常用于文件名,不是文件内容本身
2. 数据库映射注解 (System.ComponentModel.DataAnnotations.Schema
命名空间)
-
[Table]
- 作用: 指定实体类映射到的数据库表名。
- 参数:
Name
(必填): 数据库中的表名。Schema
(可选): 数据库架构名(如"dbo"
)。
- 示例:
[Table("tbl_Products", Schema = "Inventory")] public class Product {// ... }
-
[Column]
- 作用: 指定属性映射到的数据库列名及其详细信息。
- 参数:
Name
(可选): 数据库中的列名(默认使用属性名)。TypeName
(可选): 数据库中列的具体数据类型(如"varchar(100)"
,"decimal(18,2)"
)。Order
(可选): 列在数据库表中的顺序(EF Core 中通常不推荐使用)。
- 示例:
public class Product {[Column("ProductID")]public int Id { get; set; }[Column("ProductName", TypeName = "nvarchar(100)")]public string Name { get; set; }[Column("UnitPrice", TypeName = "money")]public decimal Price { get; set; } }
-
[Key]
- 作用: 标识属性作为实体类的主键。
- 示例:
public class Customer {[Key]public int CustomerId { get; set; }// ... }
-
[DatabaseGenerated]
- 作用: 指定数据库如何为主键或属性生成值(如自增、计算、手动)。
- 参数:
DatabaseGeneratedOption
(必填): 枚举值 (None
-手动赋值,Identity
-数据库自增,Computed
-数据库计算)。
- 示例:
public class Order {[Key][DatabaseGenerated(DatabaseGeneratedOption.Identity)] // 最常见的用法,主键自增public int OrderId { get; set; }[DatabaseGenerated(DatabaseGeneratedOption.Computed)] // 值由数据库计算(如 GETDATE())public DateTime CreatedDate { get; set; }[DatabaseGenerated(DatabaseGeneratedOption.None)] // 必须手动赋值(如 GUID)public Guid TransactionId { get; set; } }
-
[ForeignKey]
- 作用: 指定导航属性对应的外键属性。通常放在导航属性上或外键属性上。
- 参数:
Name
(必填): 外键属性的名称(如果放在导航属性上),或导航属性的名称(如果放在外键属性上)。
- 示例 (放在导航属性上):
public class Order {public int OrderId { get; set; }public int CustomerId { get; set; } // 外键属性 (约定优先,通常不需要 [ForeignKey])[ForeignKey("CustomerId")] // 明确指定 CustomerId 是外键public Customer Customer { get; set; } // 导航属性 }
- 示例 (放在外键属性上):
public class Order {public int OrderId { get; set; }[ForeignKey("Customer")] // 明确指定 Customer 是关联的导航属性public int CustomerId { get; set; } // 外键属性public Customer Customer { get; set; } // 导航属性 }
-
[InverseProperty]
- 作用: 解决两个实体类之间有两个或多个导航属性指向对方时可能出现的歧义。指定导航属性在另一端的对应导航属性。
- 参数:
Property
(必填): 另一端对应的导航属性名称。
- 示例:
public class Employee {public int EmployeeId { get; set; }public string Name { get; set; }[InverseProperty("Supervisor")] // 在 Project 中,这个集合对应 Supervisor 导航属性public ICollection<Project> SupervisedProjects { get; set; }[InverseProperty("TeamLead")] // 在 Project 中,这个集合对应 TeamLead 导航属性public ICollection<Project> LedProjects { get; set; } }public class Project {public int ProjectId { get; set; }public string Title { get; set; }public int? SupervisorId { get; set; }[ForeignKey("SupervisorId")]public Employee Supervisor { get; set; } // 对应 Employee.SupervisedProjectspublic int TeamLeadId { get; set; }[ForeignKey("TeamLeadId")]public Employee TeamLead { get; set; } // 对应 Employee.LedProjects }
-
[NotMapped]
- 作用: 标记属性不应映射到数据库字段。常用于计算属性、临时属性或仅用于 UI 的属性。
- 示例:
public class Product {public int Id { get; set; }public string Name { get; set; }public decimal Price { get; set; }public decimal TaxRate { get; set; }[NotMapped] // 这个属性不会存入数据库public decimal PriceWithTax => Price * (1 + TaxRate); // 计算属性 }
-
[Timestamp]
- 作用: 将属性标记为数据库中的行版本/时间戳列(通常类型为
byte[]
)。用于实现乐观并发控制。数据库会在更新行时自动更新此值。EF Core 检测到[Timestamp]
会自动使用此属性进行并发检查。 - 示例:
public class Blog {public int BlogId { get; set; }public string Url { get; set; }[Timestamp]public byte[] RowVersion { get; set; } // SQL Server 对应 rowversion 类型 }
- 作用: 将属性标记为数据库中的行版本/时间戳列(通常类型为
-
[ConcurrencyCheck]
- 作用: 标记属性参与乐观并发检查。当更新实体时,EF Core 会在 WHERE 子句中包含此属性的原始值。如果更新后数据库中的值已改变(被其他用户修改),则抛出
DbUpdateConcurrencyException
。[Timestamp]
是更高效、更常用的方式。 - 示例:
public class Author {public int AuthorId { get; set; }public string Name { get; set; }[ConcurrencyCheck] // 这个字段参与并发检查public int Revision { get; set; } }
- 作用: 标记属性参与乐观并发检查。当更新实体时,EF Core 会在 WHERE 子句中包含此属性的原始值。如果更新后数据库中的值已改变(被其他用户修改),则抛出
3. 序列化/反序列化相关注解 (System.Text.Json.Serialization
或 Newtonsoft.Json
命名空间)
-
[JsonIgnore]
(System.Text.Json 或 Newtonsoft.Json)- 作用: 序列化或反序列化时忽略此属性。
- 示例:
public class User {public int Id { get; set; }public string Username { get; set; }[JsonIgnore] // 密码不会出现在序列化结果中,也不会从客户端接收public string PasswordHash { get; set; } }
-
[JsonPropertyName]
(System.Text.Json) /[JsonProperty]
(Newtonsoft.Json)- 作用: 指定属性在 JSON 中的名称。
- 参数:
Name
(必填): JSON 中使用的属性名。
- 示例 (System.Text.Json):
public class Product {[JsonPropertyName("product_id")]public int Id { get; set; }[JsonPropertyName("product_name")]public string Name { get; set; } }
- 示例 (Newtonsoft.Json):
public class Product {[JsonProperty("product_id")]public int Id { get; set; }[JsonProperty("product_name")]public string Name { get; set; } }
-
[JsonConverter]
(System.Text.Json 或 Newtonsoft.Json)- 作用: 为属性或类型指定自定义的 JSON 转换器,用于处理特殊的序列化/反序列化逻辑。
- 参数:
Type
(通常): 转换器类型的Type
对象。ConverterType
(Newtonsoft.Json): 同上。
- 示例 (System.Text.Json 自定义 DateTime 格式):
public class CustomDateTimeConverter : JsonConverter<DateTime> {private readonly string _format;public CustomDateTimeConverter(string format) => _format = format;public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)=> DateTime.ParseExact(reader.GetString(), _format, CultureInfo.InvariantCulture);public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)=> writer.WriteStringValue(value.ToString(_format, CultureInfo.InvariantCulture)); }public class Event {[JsonConverter(typeof(CustomDateTimeConverter), "yyyy-MM-dd HH:mm:ss")]public DateTime StartTime { get; set; } }
-
[JsonInclude]
(System.Text.Json)- 作用: 在序列化/反序列化时包含非公共成员(如
internal
或private
setter)。通常用于不可变类型。 - 示例:
public record Point(int X, int Y) {[JsonInclude] // 允许反序列化时设置这个计算属性(通常需要配套方法)public double DistanceFromOrigin => Math.Sqrt(X * X + Y * Y); }
- 作用: 在序列化/反序列化时包含非公共成员(如