簡體   English   中英

FluentValidation 比較來自不同類的 2 個值

[英]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 示例(包含CustomMust驗證器的示例):

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM