using System.ComponentModel.DataAnnotations;
namespace Dpz.Core.Auth.Models;
public class ChangePasswordModel : IValidatableObject
{
/// <summary>
/// 当前密码
/// </summary>
[Required(ErrorMessage = "请输入当前密码")]
[Display(Name = "当前密码")]
public string? Password { get; set; }
/// <summary>
/// 新密码
/// </summary>
[Required(ErrorMessage = "请输入新密码")]
[StringLength(100, MinimumLength = 8, ErrorMessage = "新密码长度必须在8-100个字符之间")]
[RegularExpression(
@"^[\x21-\x7E]{8,}$",
ErrorMessage = "新密码只能包含ASCII可打印字符,不能包含空格"
)]
[Display(Name = "新密码")]
public string? NewPassword { get; set; }
/// <summary>
/// 新密码确认
/// </summary>
[Required(ErrorMessage = "请确认新密码")]
[Display(Name = "确认新密码")]
public string? NewRepeatPassword { get; set; }
/// <summary>
/// 双因素验证码(如已启用)
/// </summary>
[StringLength(6, MinimumLength = 6, ErrorMessage = "验证码必须为6位数字")]
[RegularExpression(@"^\d{6}$", ErrorMessage = "验证码必须为6位数字")]
[Display(Name = "双因素验证码")]
public string? PinCode { get; set; }
/// <summary>
/// 自定义验证逻辑
/// </summary>
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
// 验证新密码确认
if (!string.IsNullOrEmpty(NewPassword) && !string.IsNullOrEmpty(NewRepeatPassword))
{
if (NewPassword != NewRepeatPassword)
{
yield return new ValidationResult(
"新密码与确认密码不匹配",
new[] { nameof(NewRepeatPassword) }
);
}
}
// 验证新密码不能与当前密码相同
if (!string.IsNullOrEmpty(Password) && !string.IsNullOrEmpty(NewPassword))
{
if (Password == NewPassword)
{
yield return new ValidationResult(
"新密码不能与当前密码相同",
new[] { nameof(NewPassword) }
);
}
}
}
}
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
这是一个用于用户修改密码功能的数据模型类,实现了 IValidatableObject 接口来提供自定义验证逻辑。让我详细解释一下代码的各个部分:
类概述
public class ChangePasswordModel : IValidatableObject
这个类继承了 IValidatableObject 接口,允许实现自定义的验证逻辑。
属性详解
1. 当前密码 (Password)
[Required(ErrorMessage = "请输入当前密码")]
[Display(Name = "当前密码")]
public string? Password { get; set; }
- 使用
Required特性标记为必填字段 - 用于验证用户身份的当前密码
2. 新密码 (NewPassword)
[Required(ErrorMessage = "请输入新密码")]
[StringLength(100, MinimumLength = 8, ErrorMessage = "新密码长度必须在8-100个字符之间")]
[RegularExpression(@"^[\x21-\x7E]{8,}$", ErrorMessage = "新密码只能包含ASCII可打印字符,不能包含空格")]
[Display(Name = "新密码")]
public string? NewPassword { get; set; }
- 必填验证:确保用户输入新密码
- 长度验证:密码长度必须在8-100个字符之间
- 格式验证:正则表达式
[\x21-\x7E]{8,}确保密码只包含ASCII可打印字符(不包含空格),提高安全性
3. 新密码确认 (NewRepeatPassword)
[Required(ErrorMessage = "请确认新密码")]
[Display(Name = "确认新密码")]
public string? NewRepeatPassword { get; set; }
- 用于确保用户正确输入了新密码
4. 双因素验证码 (PinCode)
[StringLength(6, MinimumLength = 6, ErrorMessage = "验证码必须为6位数字")]
[RegularExpression(@"^\d{6}$", ErrorMessage = "验证码必须为6位数字")]
[Display(Name = "双因素验证码")]
public string? PinCode { get; set; }
- 可选字段(没有 Required 特性)
- 如果启用了双因素认证,需要输入6位数字验证码
- 正则表达式
^\d{6}$确保输入的是恰好6位数字
自定义验证逻辑
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
这个方法实现了两个重要的业务验证规则:
1. 新密码一致性验证
if (NewPassword != NewRepeatPassword)
{
yield return new ValidationResult(
"新密码与确认密码不匹配",
new[] { nameof(NewRepeatPassword) }
);
}
确保用户在两个密码字段中输入了相同的密码。
2. 密码差异性验证
if (Password == NewPassword)
{
yield return new ValidationResult(
"新密码不能与当前密码相同",
new[] { nameof(NewPassword) }
);
}
防止用户将新密码设置为与当前密码相同的值。
设计优点
- 多层验证:结合了特性验证和自定义验证逻辑
- 安全性考虑:密码复杂度要求、长度限制
- 用户体验:清晰的错误提示信息
- 扩展性:支持双因素认证
- 可维护性:代码结构清晰,易于理解和修改
这个模型类非常适合用在Web应用程序的密码修改功能中,提供了完整的验证机制来确保密码修改过程的安全性和用户体验。
AI 正在分析代码…
评论加载中...