[英]FluentValidation compare 2 values from different classes
我在模型中有 2 個類,我想驗證一個類的字段中的值小於第二個類的字段。 我瀏覽了 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 不能大於跨度。
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 存儲庫作為構造函數;驗證仍然是服務器端,但可以在中間件中自動完成)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.