FluentValidation - 验证列表中的字符串
FluentValidation - Validation of strings inside a list
我正在尝试创建一个验证来检查两个列表中的电子邮件地址。电子邮件地址不能在抄送列表和密送列表中重复。
我有这个型号:
public class EmailEnforceListingGroup : EnforceListingGroup
{
public string TemplateId { get; set; }
public string ToEmail { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public string CcEmail { get; set; }
public string BccEmail { get; set; }
public IList<EnforceFileAttachment> Attachments { get; set; }
public IList<string> CcEmailList => !CcEmail.IsNullOrEmpty() ? CcEmail.Split(',', ';').ToList() : new List<string>();
public IList<string> BccEmailList => !BccEmail.IsNullOrEmpty() ? BccEmail.Split(',', ';').ToList() : new List<string>();
public EmailEnforceListingGroup()
{
Attachments = new List<EnforceFileAttachment>();
}
}
我创建了这个验证器:
public class EmailEnforceListingGroupValidator : AbstractValidator<EmailEnforceListingGroup>
{
public EmailEnforceListingGroupValidator()
{
RuleFor(x => x.TemplateId)
.NotEmpty();
RuleFor(x => x.ToEmail)
.NotEmpty()
.EmailAddress();
RuleFor(x => x.Subject)
.NotEmpty();
RuleFor(x => x.Body)
.NotEmpty();
RuleForEach(x => x.CcEmailList)
.EmailAddress();
RuleForEach(x => x.BccEmailList)
.EmailAddress();
RuleFor(x => x)
.Must(emailEnforce => !IsDuplicated(emailEnforce.ToEmail, emailEnforce.CcEmailList.ToList()))
.WithMessage("The field [Cc] contains an Email Address that already exists in the [To] field.");
RuleFor(x => x)
.Must(emailEnforce => !IsDuplicated(emailEnforce.ToEmail, emailEnforce.BccEmailList.ToList()))
.WithMessage("The field [Bcc] contains an Email Address that already exists in the [To] field.");
RuleFor(emailEnforce =>
RuleForEach(eachEmail => eachEmail.CcEmailList)
.Must(email => !IsDuplicated(email, emailEnforce.BccEmailList.ToList()))
.WithMessage("The field [Bcc] contains an Email Address that already exists in the [Cc] field."));
}
private bool IsDuplicated(string email, List<string> listToCheck)
{
return listToCheck.Any(x => x.Equals(email));
}
}
将 RuleForEach 和 SetValidator 用于新的自定义验证器是一种可能的方法,但我不知道如何将 BccList 与每个 CcEmail 一起发送以查看它是否存在于另一个列表中。
使用 RuleFor 和 Must 的两个验证工作正常,但使用 RuleFor、RuleForEach 和 Must 的验证器没有发现任何错误。
已编辑:
我用这种方法解决了问题
RuleForEach(emailEnforce => emailEnforce.CcEmailList)
.Must((emailEnforce, email) => !IsDuplicated(email, emailEnforce.BccEmailList.ToList()))
.WithMessage(
"The field [Bcc] contains an Email Address ({PropertyValue}) that already exists in the [Cc] field.");
解释在link下面
我还没有机会测试这段代码,但它应该是这样的。如果您查看 FV 自定义验证器页面 (https://fluentvalidation.net/custom-validators),您将看到您可以在自定义函数中访问根对象,因此我的 BeUniqueEmail() 的第一个参数是根对象,然后您可以访问通过模型的任何其他 属性。这样您就可以访问您的 BccList,并且可以轻松进行比较。电子邮件字符串参数只是来自 RuleForEach 的 CcEmailList 中的每封电子邮件。没有理由将 RuleForEach 嵌套在 RuleFor 中。
RuleForEach(x => x.CcEmailList )
.BeUniqueEmail()
.WithMessage("The field [Bcc] contains an Email Address that already exists in the [Cc] field.");
private bool BeUniqueEmail(EmailEnforceListingGroup model, string email)
{
return model.BccEmailList.Any(x => x.Equals(email));
}
我正在尝试创建一个验证来检查两个列表中的电子邮件地址。电子邮件地址不能在抄送列表和密送列表中重复。
我有这个型号:
public class EmailEnforceListingGroup : EnforceListingGroup
{
public string TemplateId { get; set; }
public string ToEmail { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public string CcEmail { get; set; }
public string BccEmail { get; set; }
public IList<EnforceFileAttachment> Attachments { get; set; }
public IList<string> CcEmailList => !CcEmail.IsNullOrEmpty() ? CcEmail.Split(',', ';').ToList() : new List<string>();
public IList<string> BccEmailList => !BccEmail.IsNullOrEmpty() ? BccEmail.Split(',', ';').ToList() : new List<string>();
public EmailEnforceListingGroup()
{
Attachments = new List<EnforceFileAttachment>();
}
}
我创建了这个验证器:
public class EmailEnforceListingGroupValidator : AbstractValidator<EmailEnforceListingGroup>
{
public EmailEnforceListingGroupValidator()
{
RuleFor(x => x.TemplateId)
.NotEmpty();
RuleFor(x => x.ToEmail)
.NotEmpty()
.EmailAddress();
RuleFor(x => x.Subject)
.NotEmpty();
RuleFor(x => x.Body)
.NotEmpty();
RuleForEach(x => x.CcEmailList)
.EmailAddress();
RuleForEach(x => x.BccEmailList)
.EmailAddress();
RuleFor(x => x)
.Must(emailEnforce => !IsDuplicated(emailEnforce.ToEmail, emailEnforce.CcEmailList.ToList()))
.WithMessage("The field [Cc] contains an Email Address that already exists in the [To] field.");
RuleFor(x => x)
.Must(emailEnforce => !IsDuplicated(emailEnforce.ToEmail, emailEnforce.BccEmailList.ToList()))
.WithMessage("The field [Bcc] contains an Email Address that already exists in the [To] field.");
RuleFor(emailEnforce =>
RuleForEach(eachEmail => eachEmail.CcEmailList)
.Must(email => !IsDuplicated(email, emailEnforce.BccEmailList.ToList()))
.WithMessage("The field [Bcc] contains an Email Address that already exists in the [Cc] field."));
}
private bool IsDuplicated(string email, List<string> listToCheck)
{
return listToCheck.Any(x => x.Equals(email));
}
}
将 RuleForEach 和 SetValidator 用于新的自定义验证器是一种可能的方法,但我不知道如何将 BccList 与每个 CcEmail 一起发送以查看它是否存在于另一个列表中。
使用 RuleFor 和 Must 的两个验证工作正常,但使用 RuleFor、RuleForEach 和 Must 的验证器没有发现任何错误。
已编辑:
我用这种方法解决了问题
RuleForEach(emailEnforce => emailEnforce.CcEmailList)
.Must((emailEnforce, email) => !IsDuplicated(email, emailEnforce.BccEmailList.ToList()))
.WithMessage(
"The field [Bcc] contains an Email Address ({PropertyValue}) that already exists in the [Cc] field.");
解释在link下面
我还没有机会测试这段代码,但它应该是这样的。如果您查看 FV 自定义验证器页面 (https://fluentvalidation.net/custom-validators),您将看到您可以在自定义函数中访问根对象,因此我的 BeUniqueEmail() 的第一个参数是根对象,然后您可以访问通过模型的任何其他 属性。这样您就可以访问您的 BccList,并且可以轻松进行比较。电子邮件字符串参数只是来自 RuleForEach 的 CcEmailList 中的每封电子邮件。没有理由将 RuleForEach 嵌套在 RuleFor 中。
RuleForEach(x => x.CcEmailList )
.BeUniqueEmail()
.WithMessage("The field [Bcc] contains an Email Address that already exists in the [Cc] field.");
private bool BeUniqueEmail(EmailEnforceListingGroup model, string email)
{
return model.BccEmailList.Any(x => x.Equals(email));
}