FluentValidation 比较来自不同 类 的 2 个值
FluentValidation compare 2 values from different classes
我在模型中有 2 个 class,我想验证一个 class 的字段中的值小于第二个 class 的字段。我浏览了 Fluent 文档,但找不到真实示例。
public class inputModel
{
public double Iy { get; set; }
public bool selfWeight { get; set; }
public double span { get; set; }
public string spanType { get; set; }
}
public class pointLoad
{
public double pLoad { get; set; }
public double pDist { get; set; }
}
我需要验证字段 pDist 不能大于 span。
public class pointLoadFluentValidator : AbstractValidator<pointLoad>
{
public pointLoadFluentValidator()
{
RuleFor(x => x.pLoad)
.NotEmpty()
.NotNull()
.LessThan(9999);
RuleFor(x => x.pDist)
.NotEmpty()
.NotNull()
.LessThan(99);
}
谢谢。
假设您使用的是最新版本的 FV,并且无法在模型之间建立关系,我通常会使用 RootDataContext 来解决这个问题。您还没有说明如何调用验证器,但是此方法成为服务器端调用 - 您需要手动调用验证器,因为您需要填充根数据上下文字典。
提供以上花色,则开始加规则:
RuleFor(x => x.pDist).Must((pointLoad, pDist, validationContext) =>
{
if (!validationContext.RootContextData.ContainsKey("inputModelToCompareAgainst"))
{
return true;
}
var inputModel = (inputModel)validationContext.RootContextData["inputModelToCompareAgainst"];
return pDist <= inputModel.span;
})
.WithMessage("My error message");
然后使用验证上下文调用验证器:
var validator = new pointLoadFluentValidator();
var validationContext = new ValidationContext<pointLoad>(pointLoad);
validationContext.RootContextData["inputModelToCompareAgainst"] = inputModel;
var validationResult = validator.Validate(validationContext);
工作 LINQPad 示例(包含 Custom
和 Must
验证器的示例):
void Main()
{
var fixture = new Fixture();
var pointLoad = fixture.Build<pointLoad>().With(x => x.pLoad, 10).With(x => x.pDist, 20).Create();
var inputModel = fixture.Build<inputModel>().With(x => x.span, pointLoad.pDist - 1).Create();
var validator = new pointLoadFluentValidator();
var validationContext = new ValidationContext<pointLoad>(pointLoad);
validationContext.RootContextData["inputModelToCompareAgainst"] = inputModel;
var validationResult = validator.Validate(validationContext);
validationResult.Errors.Select(x => x.ErrorMessage).Should().BeEquivalentTo(new[] { "My error message" });
}
// You can define other methods, fields, classes and namespaces here
public class inputModel
{
public double Iy { get; set; }
public bool selfWeight { get; set; }
public double span { get; set; }
public string spanType { get; set; }
}
public class pointLoad
{
public double pLoad { get; set; }
public double pDist { get; set; }
}
public class pointLoadFluentValidator : AbstractValidator<pointLoad>
{
public pointLoadFluentValidator()
{
RuleFor(x => x.pLoad)
.NotEmpty()
.NotNull()
.LessThan(9999);
RuleFor(x => x.pDist)
.NotEmpty()
.NotNull()
.LessThan(99);
//pointLoad.pDist cannot be greater than inputModel.span, therefore pointLoad.pDist must be less than or equal to inputModel.span
//RuleFor(x => x.pDist).Custom((pDist, validationContext) =>
//{
// if (validationContext.RootContextData.ContainsKey("inputModelToCompareAgainst"))
// {
// var inputModel = (inputModel)validationContext.RootContextData["inputModelToCompareAgainst"];
// if (pDist > inputModel.span)
// validationContext.AddFailure("My error message");
// }
//});
RuleFor(x => x.pDist).Must((pointLoad, pDist, validationContext) =>
{
if (!validationContext.RootContextData.ContainsKey("inputModelToCompareAgainst"))
{
return true;
}
var inputModel = (inputModel)validationContext.RootContextData["inputModelToCompareAgainst"];
return pDist <= inputModel.span;
})
.WithMessage("My error message");
}
}
如果您依赖 HTTP 请求管道中间件来调用验证器,那么我们需要更多信息。听起来 inputModel 是用户输入。 pointLoad 也是输入吗?它是来自存储库的数据吗?可能还有其他选项(例如,在 inputModel 验证器中执行此验证规则,它将 pointLoad 存储库作为构造函数;验证仍然是服务器端,但可以在中间件中自动完成)。
我在模型中有 2 个 class,我想验证一个 class 的字段中的值小于第二个 class 的字段。我浏览了 Fluent 文档,但找不到真实示例。
public class inputModel
{
public double Iy { get; set; }
public bool selfWeight { get; set; }
public double span { get; set; }
public string spanType { get; set; }
}
public class pointLoad
{
public double pLoad { get; set; }
public double pDist { get; set; }
}
我需要验证字段 pDist 不能大于 span。
public class pointLoadFluentValidator : AbstractValidator<pointLoad>
{
public pointLoadFluentValidator()
{
RuleFor(x => x.pLoad)
.NotEmpty()
.NotNull()
.LessThan(9999);
RuleFor(x => x.pDist)
.NotEmpty()
.NotNull()
.LessThan(99);
}
谢谢。
假设您使用的是最新版本的 FV,并且无法在模型之间建立关系,我通常会使用 RootDataContext 来解决这个问题。您还没有说明如何调用验证器,但是此方法成为服务器端调用 - 您需要手动调用验证器,因为您需要填充根数据上下文字典。
提供以上花色,则开始加规则:
RuleFor(x => x.pDist).Must((pointLoad, pDist, validationContext) =>
{
if (!validationContext.RootContextData.ContainsKey("inputModelToCompareAgainst"))
{
return true;
}
var inputModel = (inputModel)validationContext.RootContextData["inputModelToCompareAgainst"];
return pDist <= inputModel.span;
})
.WithMessage("My error message");
然后使用验证上下文调用验证器:
var validator = new pointLoadFluentValidator();
var validationContext = new ValidationContext<pointLoad>(pointLoad);
validationContext.RootContextData["inputModelToCompareAgainst"] = inputModel;
var validationResult = validator.Validate(validationContext);
工作 LINQPad 示例(包含 Custom
和 Must
验证器的示例):
void Main()
{
var fixture = new Fixture();
var pointLoad = fixture.Build<pointLoad>().With(x => x.pLoad, 10).With(x => x.pDist, 20).Create();
var inputModel = fixture.Build<inputModel>().With(x => x.span, pointLoad.pDist - 1).Create();
var validator = new pointLoadFluentValidator();
var validationContext = new ValidationContext<pointLoad>(pointLoad);
validationContext.RootContextData["inputModelToCompareAgainst"] = inputModel;
var validationResult = validator.Validate(validationContext);
validationResult.Errors.Select(x => x.ErrorMessage).Should().BeEquivalentTo(new[] { "My error message" });
}
// You can define other methods, fields, classes and namespaces here
public class inputModel
{
public double Iy { get; set; }
public bool selfWeight { get; set; }
public double span { get; set; }
public string spanType { get; set; }
}
public class pointLoad
{
public double pLoad { get; set; }
public double pDist { get; set; }
}
public class pointLoadFluentValidator : AbstractValidator<pointLoad>
{
public pointLoadFluentValidator()
{
RuleFor(x => x.pLoad)
.NotEmpty()
.NotNull()
.LessThan(9999);
RuleFor(x => x.pDist)
.NotEmpty()
.NotNull()
.LessThan(99);
//pointLoad.pDist cannot be greater than inputModel.span, therefore pointLoad.pDist must be less than or equal to inputModel.span
//RuleFor(x => x.pDist).Custom((pDist, validationContext) =>
//{
// if (validationContext.RootContextData.ContainsKey("inputModelToCompareAgainst"))
// {
// var inputModel = (inputModel)validationContext.RootContextData["inputModelToCompareAgainst"];
// if (pDist > inputModel.span)
// validationContext.AddFailure("My error message");
// }
//});
RuleFor(x => x.pDist).Must((pointLoad, pDist, validationContext) =>
{
if (!validationContext.RootContextData.ContainsKey("inputModelToCompareAgainst"))
{
return true;
}
var inputModel = (inputModel)validationContext.RootContextData["inputModelToCompareAgainst"];
return pDist <= inputModel.span;
})
.WithMessage("My error message");
}
}
如果您依赖 HTTP 请求管道中间件来调用验证器,那么我们需要更多信息。听起来 inputModel 是用户输入。 pointLoad 也是输入吗?它是来自存储库的数据吗?可能还有其他选项(例如,在 inputModel 验证器中执行此验证规则,它将 pointLoad 存储库作为构造函数;验证仍然是服务器端,但可以在中间件中自动完成)。