1

There are several posts on this. I'm on 3.9.71 by the way.

The first one is here, answered by @Scott. In general, you can't really access the session using something similar to Service.SessionAs<> simply because validation kicks in before the service is even executed.

The second one is here, answered by @paaschpa. In here, there is a way to get hold of the session, even in the validation phase, since technically we have

  • The CacheClient, which can be injected into the validator
  • The underlying request, which will be retrieved internally within SessionFeature.GetSessionKey(). The method checks for ServiceStack's own IHttpRequest, failing which it will fallback on HttpContext.Current.Request. Obviously since we didn't pass anything into SessionFeature.GetSessionKey() the method goes for HttpContext.Current.Request, which is really ASP.NET specific.

Once you configure ServiceStack for self-hosted mode, this fails since we don't have HttpContext.Current.Request. Following is the code that fails (GetSessionId is invoked by GetSessionKey).

public static string GetSessionId(IHttpRequest httpReq = null)
{
    if (httpReq == null && HttpContext.Current == null)
    {
        throw new NotImplementedException("Only ASP.NET Requests accessible via Singletons are supported");
    }
    httpReq = (httpReq ?? HttpContext.Current.Request.ToRequest(null));
    return httpReq.GetSessionId();
}

It seems to be a case of so close yet so far. Any way we can get hold of IHttpRequest in the validator?

Update

Looking at the ValidationFilters.RequestFilter action in ServiceStackV3, it seems like the intention is already there. Note how if the validator implements IRequiresHttpRequest, it injects the request into the validator.

public static class ValidationFilters
{
    public static void RequestFilter(IHttpRequest req, IHttpResponse res, object requestDto)
    {
        var validator = ValidatorCache.GetValidator(req, requestDto.GetType());
        if (validator == null) return;

        var validatorWithHttpRequest = validator as IRequiresHttpRequest;
        if (validatorWithHttpRequest != null)
            validatorWithHttpRequest.HttpRequest = req;

        var ruleSet = req.HttpMethod;
        var validationResult = validator.Validate(
            new ValidationContext(requestDto, null, new MultiRuleSetValidatorSelector(ruleSet)));

I tried implementing the IRequiresHttpRequest interface on my validator, but unfortunately it is still null. Apparently this is due to a bug on my code, so it's not an issue.

Community
  • 1
  • 1
boyan
  • 1,115
  • 1
  • 8
  • 11

1 Answers1

1

As per the update above, the trick is to ensure your validator implements IRequiresHttpRequest, and you're good to go!

public MyDtoValidator : AbstractValidator<MyDto>, IRequiresHttpRequest

The validation filter will then inject the request on your behalf as it fires up the validator. You can then get the request via the property HttpRequest. I've tested this on a simpler solution, and it worked.

boyan
  • 1,115
  • 1
  • 8
  • 11