ServiceStack + FluentValidation not triggering with ResolveService

449 Views Asked by At

I'm using ServiceStack + FluentValidation v3.

I can post directly to the API and experience request validation, however, when calling from a resolved service instance in my MVC controller, no validation is triggered.

Using Fiddler, I POST the following:

POST /api/json/oneway/FieldSample HTTP/1.1
Content-Type: application/json
Content-Length: 66
Host: localhost:53185

{"Sample.Id":"2866246","Sample.SampleTime":"6/7/1950 12:00:00 PM"}

Response, as desired:

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Content-Length: 138
Connection: Close

{"responseStatus":{"errorCode":"LessThan","message":"TestTest","errors":[{"errorCode":"LessThan","fieldName":"Id","message":"TestTest"}]}}

From my MVC Controller:

using (var svc = AppHostBase.ResolveService<FieldSampleService>(System.Web.HttpContext.Current))
    {
        try { svc.Post(model.Sample); }
        catch (WebServiceException webEx)
        {
            return Json(new { Success = false }, "text/html");
        }
    }

No exception is thrown.

Manually creating an instance of the IValidator in the Service and throwing the exception DOES bubble the exception.


Why is the validation not triggering against requests originating from the AppHostBase.ResolveService?

1

There are 1 best solutions below

3
On BEST ANSWER

I've made two discoveries here, though I'd like to see if anyone with more thorough knowledge of the source can confirm or disprove them.


AppHostBase.ResolveService vs. JsonServiceClient

Changing my connection method to the following triggers validation.

using (var client = new JsonServiceClient(baseUri)) {
    client.Post(model.Sample);
}

The AppHostBase.ResolveService just returns an instance from the IoC container (like it should), but my assumption was that the instance would still use the same request filters/pipeline which is what triggers the validation. It makes sense that it's not the more I think about it, but it behavior certainly isn't obvious when considering the request filter validation method.


IReturnVoid prevents WebServiceException

Once I crossed that hurdle, I was having issues getting the FluentValidation error messages back. The docs show that a WebServiceException would be thrown containing the validation details, but I was getting a WebException. I finally realized my Request DTO was implementing IReturnVoid. This appears to determine which type of exception is thrown. Changing it to IReturn<any type> caused the WebServiceException to be thrown as desired.