3

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?

Jeremy Smith
  • 1,349
  • 8
  • 15

1 Answers1

1

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.

Jeremy Smith
  • 1,349
  • 8
  • 15
  • To clarify, the `WebServiceException` you refer to is related to the service client, right? So it's probably the service client that is making the validation failure exception unavailable when it sees the request DTO is `IReturnVoid`. On the server side, the `IReturnVoid` marker should not change whether an error response is returned in general for validation failures. – Mike Mertsock Jan 17 '14 at 20:10
  • Concerning the `WebServiceException`, yes. It does seem the client is controlling it. However, the underlying issue is that the validation doesn't get triggered at all when using the resolved service reference. The RequestFilter validation scheme allows the implementation to assume incoming requests are valid, so any deviation from this could cause some real problems. Hopefully I'm just misusing it or misunderstanding as I really want this to work this way. – Jeremy Smith Jan 18 '14 at 20:18
  • 1
    Yeah, that's all correct. Just wanted to highlight some of the details of what was going on to those who may be interested. – Mike Mertsock Jan 19 '14 at 01:37