C# FluentValidation:更新验证程序中一些可选属性的验证模型

C# FluentValidation:更新验证程序中一些可选属性的验证模型,c#,fluentvalidation,C#,Fluentvalidation,我想知道,如果这些参数无效,是否可以在FluentValidations验证器中更新一些可选参数的已验证模型 下面是一些代码: public class Customer { public string FirstName { get; set; } public string MiddleName { get; set; } public string LastName { get; set; } } public class CustomerValidator :

我想知道,如果这些参数无效,是否可以在FluentValidations验证器中更新一些可选参数的已验证模型

下面是一些代码:

public class Customer
{
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
}

public class CustomerValidator : AbstractValidator<Customer>
{
    public CustomerValidator()
    {
        RuleFor(customer => customer.FirstName).NotNull().Length(5, 100);
        RuleFor(customer => customer.LastName).NotNull().Length(5, 100);
        RuleFor(customer => customer.MiddleName).Length(5, 100).When(c => string.IsNullOrWhiteSpace(c.MiddleName));
    }
}

因此,在我的例子中,我想在中间名无效时将其设置为null,并在变量中保存一条警告,但仍将模型视为有效。

实际操作传入的值不仅仅是验证。所以FluentValidator可能不是最好的地方。把那个特殊的逻辑放在setter里怎么样

string middleName;
public string MiddleName { 
    get => middleName; 
    set { 
        middleName = 
            value.Length < 5 || value.Length > 100 
            ? null 
            : value; 
    } 
字符串名称;
公共字符串名称{
get=>middleName;
集合{
中间名=
值.长度<5 | |值.长度>100
无效的
:价值;
} 

编辑:回应评论中提出的问题

所以,关于您想要显示警告消息的愿望。我假设您已经知道如何在FluentValidation中执行此操作。这似乎不是一个有趣的主题,至少在我查找资源时是这样。因此,我将在这个响应中保留实际的警告逻辑

但是,为了让您有机会发出这样的警告,您需要将其存储在某个位置。因此,只需为此添加一个字段,并在setter逻辑中处理它:

public string middleNameWarning;

string middleName;
public string MiddleName { 

    get => middleName; 

    set { 

        if (value.Length < 5 || value.Length > 100) {
            middleName = null;
            middleNameWarning = 
                $"'{value}' is not a valid MiddleName.  It was reset to null. "
                + "Set MiddleName explicitly to a valid value to remove this warning.";
        }
        else {
            middleName = value;
            middleNameWarning = null;
        }

    }

}
公共字符串middleNameWarning;
字符串名称;
公共字符串名称{
get=>middleName;
集合{
如果(value.Length<5 | | value.Length>100){
middleName=null;
middleNameWarning=
$“{value}”不是有效的中间名。已将其重置为null
+“将MiddleName显式设置为有效值以删除此警告。”;
}
否则{
中间名=值;
middleNameWarning=null;
}
}
}
middleNameWarning
必须是公共的,才能通过FluentValidation访问它(我能够确认这一点)。如果你不喜欢,也许你可以让一个方法访问它。此外,它可能只是一个布尔值,当你发现它的值为真时,你可以在别处设置文本

最后,为了确认您最初的方法可能不会如您所希望的那样奏效,我在GitHub存储库上发现了一个封闭的窗口,供有人询问如何做类似的事情。下面是JeremySkinner的回复:

您好,FluentValidation只对预填充的对象执行验证,它不会修改/更改属性的值。从技术上讲,您可以使用自定义验证程序来完成这项工作,但我不推荐这样做


实际上,操作传入的值不仅仅是验证。因此FluentValidator可能不是它的最佳位置。将特定逻辑放入setter如何

string middleName;
public string MiddleName { 
    get => middleName; 
    set { 
        middleName = 
            value.Length < 5 || value.Length > 100 
            ? null 
            : value; 
    } 
字符串名称;
公共字符串名称{
get=>middleName;
集合{
中间名=
值.长度<5 | |值.长度>100
无效的
:价值;
} 

编辑:回应评论中提出的问题

所以,关于您想要显示警告消息的愿望。我假设您已经知道如何在FluentValidation中执行此操作。这似乎不是一个有趣的主题,至少在我查找资源时是这样。因此,我将在这个响应中保留实际的警告逻辑

但是,为了让您有机会发出这样的警告,您需要将其存储在某个位置。因此,只需为此添加一个字段,并在setter逻辑中处理它:

public string middleNameWarning;

string middleName;
public string MiddleName { 

    get => middleName; 

    set { 

        if (value.Length < 5 || value.Length > 100) {
            middleName = null;
            middleNameWarning = 
                $"'{value}' is not a valid MiddleName.  It was reset to null. "
                + "Set MiddleName explicitly to a valid value to remove this warning.";
        }
        else {
            middleName = value;
            middleNameWarning = null;
        }

    }

}
公共字符串middleNameWarning;
字符串名称;
公共字符串名称{
get=>middleName;
集合{
如果(value.Length<5 | | value.Length>100){
middleName=null;
middleNameWarning=
$“{value}”不是有效的中间名。已将其重置为null
+“将MiddleName显式设置为有效值以删除此警告。”;
}
否则{
中间名=值;
middleNameWarning=null;
}
}
}
middleNameWarning
必须是公共的,才能通过FluentValidation访问它(我能够确认这一点)。如果你不喜欢,也许你可以让一个方法访问它。此外,它可能只是一个布尔值,当你发现它的值为真时,你可以在别处设置文本

最后,为了确认您最初的方法可能不会如您所希望的那样奏效,我在GitHub存储库上发现了一个封闭的窗口,供有人询问如何做类似的事情。下面是JeremySkinner的回复:

您好,FluentValidation只对预填充的对象执行验证,它不会修改/更改属性的值。从技术上讲,您可以使用自定义验证程序来完成这项工作,但我不推荐这样做


更新传递给验证的对象不是一个好主意。验证程序应该只验证输入实体,并返回验证结果。我建议您有两个验证程序。一个用于业务关键规则,一个用于警告,因此如果第一个验证程序返回的模型无效,您将返回结果,如果o严重错误,然后验证警告,然后决定是否继续并使用模型进行操作! 比如说

    public class Customer
{
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
}

public class CustomerCriticalValidator : AbstractValidator<Customer>
{
    public CustomerValidator()
    {
        RuleFor(customer => customer.FirstName).NotNull().Length(5, 100);
        RuleFor(customer => customer.LastName).NotNull().Length(5, 100);
    }
}

public class CustomerWarningValidator : AbstractValidator<Customer>
{
    public CustomerValidator()
    {

        RuleFor(customer => customer.MiddleName).Length(5, 100).When(c => string.IsNullOrWhiteSpace(c.MiddleName));
    }
}

更新传递给验证的对象不是一个好主意。验证程序应该只验证输入实体,并返回验证结果。我建议您有两个验证程序。一个用于业务关键规则,一个用于警告,因此如果第一个验证程序返回的模型无效,您将返回结果,如果o严重错误,然后验证警告,然后决定是否继续并使用模型进行操作! 比如说

    public class Customer
{
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
}

public class CustomerCriticalValidator : AbstractValidator<Customer>
{
    public CustomerValidator()
    {
        RuleFor(customer => customer.FirstName).NotNull().Length(5, 100);
        RuleFor(customer => customer.LastName).NotNull().Length(5, 100);
    }
}

public class CustomerWarningValidator : AbstractValidator<Customer>
{
    public CustomerValidator()
    {

        RuleFor(customer => customer.MiddleName).Length(5, 100).When(c => string.IsNullOrWhiteSpace(c.MiddleName));
    }
}

我设法解决了这个问题:

public class CustomerValidator : AbstractValidator<Customer>
{
    public CustomerValidator()
    {
        RuleFor(customer => customer.FirstName).NotNull().Length(5, 100);
        RuleFor(customer => customer.LastName).NotNull().Length(5, 100).OnAnyFailure((customer) => 
        {
            customer.LastName = null;
            customer.Warnings.Add(nameof(customer.LastName));
        });
        RuleFor(customer => customer.MiddleName).Length(5, 100).When(c => string.IsNullOrWhiteSpace(c.MiddleName));
    }
}
公共类CustomerValidator:AbstractValidator
{
平民的