Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use custom validation responses with fluent validation #548

Closed
Rajgan opened this issue Aug 21, 2017 · 7 comments
Closed

Use custom validation responses with fluent validation #548

Rajgan opened this issue Aug 21, 2017 · 7 comments

Comments

@Rajgan
Copy link

Rajgan commented Aug 21, 2017

Looking to create custom validation response for my .net core web Api.

Here I want to have response model like
[{
ErrorCode:
ErrorField:
ErrorMsg:
}]

I want to use [CustomizeValidator] attribute instead of physically creating validator class instance to get ValidationResult .

But I am not sure how to get the ValidationResult into my controller action for me to manipulate validationresult to my custom response model.

Any advise would be much appreciated.

I have create a a question in stackoverflow
https://stackoverflow.com/questions/45758024/use-custom-validation-responses-with-fluent-validation

@JeremySkinner
Copy link
Member

JeremySkinner commented Aug 21, 2017

That's not possible I'm afraid. If you're using the automatic validation, then you will not have access to the ValidationResult inside the controller action - all the results have been copied into ModelState by this point.

You'd need to invoke the validator's Validate method manually and not rely on the automatic integration if you want access to the ValidationResult.

@Rajgan
Copy link
Author

Rajgan commented Aug 21, 2017

Yes I am trying to change it to manual validation. Instead of invoking in each action

var validator = new TestModelValidator();
    var result = validator.Validate(inputObj);
    var errorList = result.Error;

I want to use [CustomizeValidator] like this. I am sure both does the same thing.

Correct me if I am wrong..

public async Task<IActionResult> Post( [CustomizeValidator] [FromBody]TestModel request)
       {
                 
        }

I think interceptor might be helpful but I want to know if I can get ValidationResult with this format?.

The reason I am trying to use CustomizeValidator attribute is I don't want to tightly couple my validator class to my action method.

@JeremySkinner
Copy link
Member

You could use the Interceptor's AfterMvcValidation method to store the ValidationResult in the Session, which you can then retrieve from inside the controller action.

@Rajgan
Copy link
Author

Rajgan commented Aug 27, 2017

What I done is created a basevalidator class which inherited both IValidatorInterceptor and AbstractValidator. In afterMvcvalidation method if validation not successful, I mapped error from validationResult to my custom response object and throw Custom exception.

Which I Catch in my exception handling middleware and return response.

Now I am facing another issue. If I pass invalid enum the JsonFormatter fails during model binding. My Interceptor aftervalidation method is not getting called.

But somehow Modelstate is set to invalid with correct validation message. Do you have any suggestion to overcome this issue.

@JeremySkinner
Copy link
Member

JeremySkinner commented Aug 28, 2017

AfterMvcValidation is always called on the interceptor after FV is executed if you're using the automatic integration. Some things to check:

  • Is the validator definitely being executed?
  • Are any execeptions being thrown in the validation process? If so this would prevent the interceptor from running

@Rajgan
Copy link
Author

Rajgan commented Aug 28, 2017

No I guess because BeforeMvcValidation is not called.

But from googling I see modelstate.IsValid will be set to false when Json Deserialization fails during model binding and Error details will be stored in ModelState. [Which is what happening to me]

Also due to this failure Deserialization stops to continue further and get null object in controller method.

Currently I have given hack by setting serialization errorcontext.Handled = true manually and allowing my fluentvalidation to catch the invalid input.

https://www.newtonsoft.com/json/help/html/SerializationErrorHandling.htm [defined OnErrorAttribute in my request model].

I am searching for better solution but for now this hack is doing the job..

@nvivo
Copy link
Contributor

nvivo commented Aug 31, 2017

@Rajgan It's not exactly the same thing, but I did something similar to implement async validation before asp.net core. I basically bypassed all aspnet validation, implemented a filter that called the validator myself, got the results and returned a response in a dictionary the way I needed. The solution is here:

https://stackoverflow.com/questions/33278845/how-to-perform-async-modelstate-validation-with-fluentvalidation-in-web-api

I still use this to customize the results in asp.net core.

@lock lock bot locked and limited conversation to collaborators Aug 20, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants