当前位置: 首页 > 知识库问答 >
问题:

针对包含逗号分隔电子邮件的字符串进行验证

孟鸿朗
2023-03-14

我试图在MVC模型中验证此属性,该模型可以包含零个或多个以逗号分隔的电子邮件地址:

public class DashboardVM
{
    public string CurrentAbuseEmails { get; set; }
    ...
}

问题是如何使用电子邮件地址的内置fluent验证规则来实现这一点?现在我有了一个使用Must和正则表达式的解决方案,但我没有找到它。。足够优雅。

    public DashboardVMValidator()
    {
        RuleFor(x => x.CurrentAbuseEmails).Must(BeValidDelimitedEmailList).WithMessage("One or more email addresses are not valid.");
    }

    private bool BeValidDelimitedEmailList(string delimitedEmails)
    {
        //... match very very long reg. expression
    }

到目前为止,最接近的解决方案包括RuleFor(…)。EmailAddress()在下面创建了一个自定义验证器,并从字符串中对每封电子邮件调用Validate,但由于某些原因,该方法不起作用(AbuseEmailValidator无法获取谓词x)=

public class AbuseEmailValidator : AbstractValidator<string>
{
    public AbuseEmailValidator()
    {
        RuleFor(x => x).EmailAddress().WithMessage("Email address is not valid");
    }
}

有没有办法以某种简单的方式做到这一点?类似于此解决方案的东西,但使用一个字符串而不是字符串列表,因为我不能使用SetColltionValidator(或者我可以吗?):如何使用Fluent Validation对列表中的每个字符串进行验证?

共有3个答案

徐君植
2023-03-14

上面提供的答案很好,但很旧。因此,一些代码不能与永远不会版本的FluentValidationNuget包一起工作。至少我有构建错误。解决方案也可以更复杂。建议使用这个:

型号:

public sealed class Email
{
    public string From { get; set; }

    /// <summary>
    /// Email address(es) to (can be settable separated list, default: ;)
    /// </summary>
    public string To { get; set; }

    //.....

    /// <summary>
    /// Separator char for multiple email addresses
    /// </summary>
    public char EmailAddressSeparator { get; set; }

    public Email()
    {
        EmailAddressSeparator = ';';
    }
}

自定义验证程序

public static class CommonValidators
{
    public static bool CheckValidEmails(Email email, string emails)
    {
        if(string.IsNullOrWhiteSpace(emails))
        {
            return true;
        }

        var list = emails.Split(email.EmailAddressSeparator);
        var isValid = true;

        foreach (var t in list)
        {
            var email = new EmailModel { Email = t.Trim() };
            var validator = new EmailModelValidator();

            isValid = validator.Validate(email).IsValid;
            if (!isValid)
            {
                break;
            }
        }

        return isValid;
    }

    private class EmailModel
    {
        public string Email { get; set; }
    }
    private class EmailModelValidator : AbstractValidator<EmailModel>
    {
        public EmailModelValidator()
        {
            RuleFor(x => x.Email).EmailAddress(EmailValidationMode.AspNetCoreCompatible).When(x => !string.IsNullOrWhiteSpace(x.Email));
        }
    }
}

使用方法:

    public class EmailValidator : AbstractValidator<Email>
    {
        public EmailValidator()
        {
            RuleFor(x => x.To).NotEmpty()
                .Must(CommonValidators.CheckValidEmails)
                .WithMessage($"'{nameof(To)}' some of the emails provided are not a valid email address.");
        }
    }
董哲
2023-03-14

从版本9开始,FluentValidation支持此功能,而不需要使用TransformForEach方法的自定义验证器。

在9.0-9.4版本中,您可以这样写:

RuleFor(x => x.List)
    .Transform(list => list.Split(','))
    .ForEach(itemRule => itemRule.EmailAddress());

在9.5及更高版本中,RuleFor未与Transform一起使用,因此您可以这样编写:

Transform(x => x.List, list => list.Split(','))
    .ForEach(itemRule => itemRule.EmailAddress());

要处理空值,请在转换委托中使用空合并运算符:

list => (list ?? "").Split(',')

要处理空白,您可能需要修剪列表中的每个项目。您可以添加Select子句:

list => (list ?? "").Split(',')
    .Select(item => item.Trim())

如果要忽略空项,请添加where子句:

list => (list ?? "").Split(',')
    .Select(item => item.Trim())
    .Where(item => !string.IsNullOrEmpty(item))

若要要求列表中至少有一个项,请添加Not空白规则。因此,最终版本9.5代码将看起来像:

Transform(x => x.List, 
    list => (list ?? "").Split(',')
        .Select(item => item.Trim())
        .Where(item => !string.IsNullOrEmpty(item)))
    .NotEmpty()
    .ForEach(itemRule => itemRule.EmailAddress());
贡俊
2023-03-14

你可以尝试这样的方法:

public class InvoiceValidator : AbstractValidator<ContractInvoicingEditModel>
{
    public InvoiceValidator()
    {
        RuleFor(m => m.EmailAddressTo)
            .Must(CommonValidators.CheckValidEmails).WithMessage("Some of the emails   provided are not valid");
    }
}

public static class CommonValidators
{
    public static bool CheckValidEmails(string arg)
    {
        var list = arg.Split(';');
        var isValid = true;
        var emailValidator = new EmailValidator();

        foreach (var t in list)
        {
            isValid = emailValidator.Validate(new EmailModel { Email = t.Trim() }).IsValid;
            if (!isValid)
                break;
        }

        return isValid;
    }
}
public class EmailValidator : AbstractValidator<EmailModel>
{
    public EmailValidator()
    {
        RuleFor(x => x.Email).EmailAddress();
    }
}

public class EmailModel
{
    public string Email { get; set; }
}

如果你使用中介poco,它似乎工作得很好。在这种情况下,我的电子邮件由“;”分隔。希望有帮助。

 类似资料:
  • 问题内容: 我有一些特殊字符的字符串。目的是检索每行的String [](分隔)。您可以使用特殊字符“,在其中可以使用/ n和, 您会看到“ /”中有您/ n。 任何可以帮助我解析此。 谢谢 __更多说明 与主刺我需要分开这些 问题是:对于Julie,KameL,Titi ,在KameL和Titi之间存在换行符/ n,或者在Time,tomy,tony,tini之间存在类似的换行问题,或者 在to

  • 我使用以下正则表达式来验证单个电子邮件地址。如何使此正则表达式接受以逗号分隔的电子邮件地址列表? 我使用razor视图将正则表达式放置在输入标记中:

  • 问题内容: 我有从.net应用程序A,B,C,D,E,F获取的字符串, 我想写一个SQL选择语句像 这在t-SQL中将不起作用,因为它使用不将值分开的一个字符串。有什么办法可以做到这一点? 问题答案: 它认为最简单的方法是动态SQL生成:

  • 问题内容: 我有一个像 我想把它分成那些字符串 如果我简单地打电话给我,那么在修剪之后我会得到不同的结果,因为在某些字符串中,例如,仍然有一个逗号。但我不想放在方括号中。有解决这个问题的优雅方法吗? 问题答案: 假设和没有嵌套和未转义。您可以使用以下方式进行拆分: 正则演示 如果逗号后面没有非圆括号和,则将匹配逗号,从而忽略和中的逗号。

  • 问题内容: 我需要以以下方式执行选择查询: 实现该目标的正确方法是什么? 考虑到我可以控制发送字符串的客户端代码,有没有更好的方法?(该字符串将包含大约30个id,因此我试图避免发送30个参数,每个id一个)。 谢谢你们 问题答案: 您可以使用MySQL 函数: 附录 :请注意,上面的查询 无法 优化,因此,如果您在MySQL 上有索引,则不会使用它。您必须决定使用相对简单是否值得潜在的性能损失(

  • 在逗号处划分字符串的最佳方法是什么,这样每个单词都可以成为ArrayList的一个元素? 例如: