Fluent Validation报错:检查AzureAdRegister.Scopes包含AzureAd.ClientId失败
问题
尝试通过以下代码检查AzureAdRegister.Scopes是否包含AzureAd.ClientId,但启动模型验证时程序崩溃。目前已能在不使用Fluent Validation的情况下完成该检查,怀疑验证规则存在问题,请问是否是ToString()导致的该问题?
相关代码如下:
// 为了更清晰展示 public class AzureAd { public string Instance { get; set; } public string Domain { get; set; } public Guid TenantId { get; set; } public Guid ClientId { get; set; } public string CallbackPath { get; set; } public List<string> Scopes { get; set; } public List<string> DefaultScopes { get; set; } public string ClientSecret { get; set; } public List<string> ClientCertificates { get; set; } } public class AzureAdRegister { public string AuthorizationUrl { get; set; } public string TokenUrl { get; set; } public string Scopes { get; set; } public Guid ClientId { get; set; } } public class AzureConfiguration { public AzureAd AzureAd { get; set; } public AzureAdRegister AzureAdRegister { get; set;} } // 问题出在这里 public class AzureConfigurationValidator : AbstractValidator<AzureConfiguration> { public AzureConfigurationValidator() { RuleFor(azure => azure.AzureAdRegister.Scopes) .Must((azure,scope) => scope.Contains(azure.AzureAd.ClientId.ToString())) .WithMessage("注册应用的Scope必须包含主应用的ClientId"); } }
分析与解决
崩溃大概率不是ToString()本身导致的,而是空引用异常或者Guid字符串格式不匹配:
空引用风险:
- 如果
AzureAdRegister、AzureAd为null,或者AzureAdRegister.Scopes为null,调用scope.Contains()或azure.AzureAd.ClientId.ToString()都会直接触发崩溃。 - 你在普通代码里可能做了空值判断,但Fluent Validation规则里没加前置校验,所以触发了空引用异常。
- 如果
Guid格式问题:
Guid.ToString()默认返回带连字符的格式(如xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx),但如果AzureAdRegister.Scopes里存储的是不带连字符的Guid(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)或其他格式,Contains()会返回false,但不会直接崩溃——不过如果因此触发其他逻辑错误也有可能,但更常见的是空引用问题。
修正后的验证规则
添加空值前置检查,并明确Guid的字符串格式(根据你实际存储的格式调整):
public class AzureConfigurationValidator : AbstractValidator<AzureConfiguration> { public AzureConfigurationValidator() { // 先确保依赖对象不为空 RuleFor(azure => azure.AzureAd) .NotNull().WithMessage("AzureAd配置不能为空"); RuleFor(azure => azure.AzureAdRegister) .NotNull().WithMessage("AzureAdRegister配置不能为空"); RuleFor(azure => azure.AzureAdRegister.Scopes) .NotEmpty().WithMessage("注册应用的Scopes不能为空") .Must((azure, scope) => scope.Contains(azure.AzureAd.ClientId.ToString("D"))) // 指定格式,比如带连字符的D格式 .WithMessage("注册应用的Scope必须包含主应用的ClientId"); } }
额外建议
如果AzureAdRegister.Scopes是逗号分隔的字符串(比如scope1,scope2,xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx),可以先分割成列表再检查,避免部分匹配的问题(比如某个Scope包含Guid的一部分):
.Must((azure, scope) => scope.Split(',', StringSplitOptions.RemoveEmptyEntries) .Any(s => s.Trim().Equals(azure.AzureAd.ClientId.ToString("D"), StringComparison.OrdinalIgnoreCase)))
内容的提问来源于stack exchange,提问作者mohamed hassan
相关产品推荐
相关产品推荐

