NET MAUI CommunityToolkit.MVVM邮件验证属性调用时抛出异常
问题:自定义Email验证属性引发TargetInvocationException异常
我自定义了一个邮件验证属性,验证逻辑运行正常,但程序退出时会抛出System.Reflection.TargetInvocationException: 'Exception has been thrown by the target of an invocation.' 错误。移除该属性后一切恢复正常,其他自定义验证属性也能正常工作。
自定义Email验证属性代码
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] public class EmailAttribute : RegularExpressionAttribute { public EmailAttribute() : base(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}") { this.ErrorMessage = "Please provide a valid email address"; } }
模型代码
public partial class LoginModel : BaseViewModel { private string email = string.Empty; private string password = string.Empty; [Required] [MinLength(5)] [Email] public string Email { get => this.email; set { SetProperty(ref this.email, value, true); OnPropertyChanged("ErrorDictionary[Email]"); } } [Required] [DataType(DataType.Password)] [MinLength(8)] public string Password { get => this.password; set { SetProperty(ref this.password, value, true); OnPropertyChanged("ErrorDictionary[Password]"); } } }
解决方案
方案1:改用系统内置验证属性
直接替换自定义的[Email]属性为.NET内置的EmailAddressAttribute,无需自定义实现,避免反射兼容性问题:
[Required] [MinLength(5)] [EmailAddress(ErrorMessage = "Please provide a valid email address")] public string Email { ... }
方案2:重写自定义验证属性的实现
避免继承RegularExpressionAttribute,直接继承ValidationAttribute并实现验证逻辑,减少基类带来的反射冲突:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] public class EmailAttribute : ValidationAttribute { private static readonly Regex _emailRegex = new Regex(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}", RegexOptions.Compiled | RegexOptions.Singleline); public override bool IsValid(object value) { if (value is not string email) return false; return string.IsNullOrEmpty(email) || _emailRegex.IsMatch(email); } public override string FormatErrorMessage(string name) { return "Please provide a valid email address"; } }
方案3:调整ViewModel的属性变更通知逻辑
将OnPropertyChanged("ErrorDictionary[Email]")改为更标准的写法,避免字符串索引可能引发的反射问题:
OnPropertyChanged(nameof(ErrorDictionary));
或者确保ErrorDictionary的更新逻辑能够正确处理属性变更,避免在清理阶段触发异常。
内容的提问来源于stack exchange,提问作者Wasyster
相关产品推荐
相关产品推荐

