Mike Upjohn
Mike Upjohn

Reputation: 1297

FluentValidation in C# - Validation with properties in another object

I've got a class in a .NET Core 2.2 API, which I am applying Fluent Validation to. The class has an integer property public int? PurchasePrice {get;set;}.

The parent of the parent of this property, has an enum, and what I want to do is when that enum has a value of say 4, make this PurchasePrice field required.

I've started writing a custom rule as such:-

RuleFor(pd => pd.PurchasePrice).Custom((a, context) =>
{
    var parent = context.ParentContext.InstanceToValidate as ParentObject;
    var parentOfParent = context.ParentContext.ParentContext.InstanceToValidate as GrandParentObject;
});

However, the second ParentContext simply does not exist in Intellisense and also throws a compile error as it is not recognised.

Am I going the wrong way about traversing an object structure when writing validation rules?

Thanks in advance!

NB: The line to retrieve var parent works as expected.

Upvotes: 0

Views: 4156

Answers (1)

Deven Shah
Deven Shah

Reputation: 422

Perhaps When can resolve your current need here. But in case you need to write more complex validation then you can use Must. Must allows you to have access to the model being validated, so you can access any part of the model in the validation function. It is also a way of writing custom validation.

Considering the type of AdbstractValidator is the parent type (aka model) where the said enum property is you could use Must as follows:

RuleFor(pd => pd.PurchasePrice)
    .Must((model, price) => 
    { 
         return model.enum == enum.value && price != null; 
    })
    .WithMessage("Price is required when enum is of value");

Must has couple of overloads, one that expects function with the value of the property as first parameter and returns boolean. And another that takes two parameters, the model in context, the value of the property being validated and returns a boolean.

Upvotes: 4

Related Questions