2

After following the FluentValidation website, I was able to successfully implement Fluent Validation.

However, my response body looks very different and contains a lot of information. Is it possible to have a regular response body with validation errors?

I will put down the steps I took to implement Fluent Validation. Your advice and help are much appreciated. I am using Manual Validation because based on the Fluent Validation website they are not supporting the Automatic Validation anymore.

In the Program file, I added:

builder.Services.AddValidatorsFromAssemblyContaining<CityValidator>();

Then I added a class that validated my City class which has two properties Name and Description :

public class CityValidator : AbstractValidator<City>
{
    public CityValidator()
    {
        RuleFor(x => x.Name)
                .NotNull()
                .NotEmpty()
                .WithMessage("Please specify a name");
        RuleFor(x => x.Description)
                .NotNull()
                .NotEmpty()
                .WithMessage("Please specify a Description");
    }
}

In my CitiesController constructor I injected Validator<City> validator and in my Action method, I am using this code:

ValidationResult result = await _validator.ValidateAsync(city);

if (!result.IsValid)
{
    result.AddToModelState(this.ModelState);
    return BadRequest(result);
}

The AddToModelState is an extension method:

public static void AddToModelState(this ValidationResult result, ModelStateDictionary modelState)
{
    if (!result.IsValid)
    {
        foreach (var error in result.Errors)
        {
            modelState.AddModelError(error.PropertyName, error.ErrorMessage);
        }
    }
}

On POST, I am getting the response as:

{
    "isValid": false,
    "errors": [
        {
            "propertyName": "Name",
            "errorMessage": "Please specify a name",
            "attemptedValue": "",
            "customState": null,
            "severity": 0,
            "errorCode": "NotEmptyValidator",
            "formattedMessagePlaceholderValues": {
                "PropertyName": "Name",
                "PropertyValue": ""
            }
        },
        {
            "propertyName": "Description",
            "errorMessage": "Please specify a name",
            "attemptedValue": "",
            "customState": null,
            "severity": 0,
            "errorCode": "NotEmptyValidator",
            "formattedMessagePlaceholderValues": {
                "PropertyName": "Description",
                "PropertyValue": ""
            }
        }
    ],
    "ruleSetsExecuted": [
        "default"
    ]
}

While the regular response without Fluent Validation looks like this:

{
    "errors": {
        "": [
            "A non-empty request body is required."
        ],
        "pointofInterest": [
            "The pointofInterest field is required."
        ]
    },
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "00-1a68c87bda2ffb8de50b7d2888b32d02-94d30c7679aec10b-00"
}

The question: Is there a way to use Fluent Validation and get the response format like:

{
    "errors": {
        "": [
            "A non-empty request body is required."
        ],
        "pointofInterest": [
            "The pointofInterest field is required."
        ]
    },
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "00-1a68c87bda2ffb8de50b7d2888b32d02-94d30c7679aec10b-00"
}
1
  • I have updated my ans for manual validation. please check Commented Aug 23, 2022 at 18:45

2 Answers 2

2

Updated ans:

with your code, you can simply replace.

 return BadRequest(result); // replace this line with below line.
 return ValidationProblem(ModelState);

then you get same format as required.

enter image description here

------------------------*----------------------------------------

Please ignore this for manual validation.

You don't need explicit validation call.

this code is not required:

ValidationResult result = await _validator.ValidateAsync(city);

if (!result.IsValid)
{
    result.AddToModelState(this.ModelState);
    return BadRequest(result);
}

it will auto validate the model using your custom validator.

you simply need this

if (!ModelState.IsValid)
{
   return BadRequest(ModelState);
}

and it will give you errors in the require format.

Sign up to request clarification or add additional context in comments.

11 Comments

I used you code as ValidationResult result = await _validator.ValidateAsync(city); if (!result.IsValid) { //result.AddToModelState(this.ModelState); return BadRequest(result); } However, I still get the same formart
if (!result.IsValid) { //result.AddToModelState(this.ModelState); return BadRequest(); } and this will return no validation error comment
if (!result.IsValid) { result.AddToModelState(this.ModelState); return BadRequest(ModelState); } this will return { "Name": [ "Please specify a name" ], "Description": [ "Please specify a name" ] } but then the type, title and status is missing
I think you misunderstood the ans, you also need to remove ValidationResult result = await _validator.ValidateAsync(city); and only keep code what I have written.
First Thank you for your help. It seems you are using Auto validation which is not recommended. I am using manual validation.
|
0
 if(!result.IsValid)
{
        result.AddToModelState(this.ModelState);
        return ValidationProblem(ModelState);
}

Errors

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.