Reputation: 2420
I am trying to write the rules for validating field for the validation.
At first i want to check if Location Id
is empty
, null
or if that exist
in the database, and then only processed further for other validation.
But, with the code i used, only check if empty
, it does not stop if Location Id
does not exist in the database.
Register Model
public class RegisterModel
{
public long LocationId {get;set;}
public long FirstName {get;set;}
public long LastName {get;set;}
//...other property to be added
}
JSON i am passing to API:
{
"FirstName": "John",
"LocationId": "1234534",
}
The location id
does not exist in the database: But i am getting the response as:
{
"Errors": [
{
"FieldName": "LastName",
"Message": "'Last Name' must not be empty."
},
{
"FieldName": "LocationId",
"Message": "Invalid request."
}
]
}
Validation rule i am using:
public class RegisterModelValidator : AbstractValidator<RegisterModel>
{
private readonly DbContext _context;
public RegisterModelValidator(DbContext context)
{
this._context = context;
this.CascadeMode = CascadeMode.StopOnFirstFailure;
RuleFor(req => req.LocationId)
.NotEmpty().WithMessage("param1 is missing.")
.Must(IsValidRequest).WithMessage("Invalid request.");
When(x => x.LocationId != null, () => {
RuleFor(x => x.FirstName).Cascade(CascadeMode.StopOnFirstFailure).NotNull().NotEmpty();
RuleFor(x => x.LastName).Cascade(CascadeMode.StopOnFirstFailure).NotNull().NotEmpty();
});
}
private bool IsValidRequest(string req)
{
var locationId = long.TryParse(req, out long result) ? result : 0;
return _context.Locations.Any(x => x.LocationExtId == locationId);
}
private bool BeAValidDate(string value)
{
DateTime date;
return DateTime.TryParse(value, out date);
}
}
In my condition what i want is if the location id
is missing or does not exist in the database, the validation should stop immediately, it should not check for the other field.
Upvotes: 0
Views: 360
Reputation: 4179
If you look at the docs here, its mentioned as
Setting the cascade mode only applies to validators within the same RuleFor chain. Changing the cascade mode does not affect separate calls to RuleFor. If you want prevent one rule from running if a different rule fails, you should instead use
Dependent Rules
(below)
So can you try it like this using Dependent Rules
RuleFor(x => x.FirstName).NotNull().NotEmpty()
.DependentRules(d => d.RuleFor(req => req.LocationId)
.NotEmpty().WithMessage("param1 is missing.")
.Must(IsValidRequest).WithMessage("Invalid request."));
But i see if we use it like this, i think it should be repeated for multiple properties.
or a better option for you is using PreValidate
since
At first i want to check if Location Id is empty, null or if that exist in the database
Upvotes: 1