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));
}