Question

We have custom serializers for our Models that protect sensitive data depending on the request path. (For instance, if the request does not start with "/admin").

Up until now, we've tried registering the IHttpRequest with the Funq container on a RequestFilter with ReuseScope.None or ReuseScope.Request and on the serializers, we're getting the IHttpRequest from the container.

We found out that if there are multiple requests pending, the container will return that last registered IHttpRequest, which will not always be the correct request object.

I know that we could try to implement this protection of sensitive data on our models applying filter attributes, but that's very cumbersome, since our model object are often embedded in other objects or collections.

Having the serializer to do it is by far the best solution for us, if it werent for this issue of not being able to get the correct HttpRequest object from within the serializers.

So, what would be the correct way to do this? Or is this a bad practice?

Here a few code samples:

So this is a private method that my serializers use to define if they're being serialized within a "admin" route or not:

    private bool IsAdminRoute() {
        var path = container.Resolve<IHttpRequest> ().PathInfo;
        var res = path.StartsWith ("/admin");
        return res;
    }

Here's the use of it:

    public Question QuestionSerializer(Question question)
    {
        if (!IsAdminRoute())
        {
                      // do stuff like nullyfying certain properties
        }
        return question;
    }

On my AppHost initialization I have:

    void ConfigureSerializers(Funq.Container container)
    {
        Serializers = new CustomSerializers ();
                    // ...
        JsConfig<Question>.OnSerializingFn = Serializers.QuestionSerializer;
                    // ...
    }


    public void HttpRequestFilter(IHttpRequest httpReq, IHttpResponse httpRes, object dto) {
        Container.Register <IHttpRequest>(c => httpReq).ReusedWithin (Funq.ReuseScope.Request);
    }

Note: I'm using ServiceStack v3.

Was it helpful?

Solution

I managed to make it work by registering the IHttpRequest this way:

        container.Register(c => HttpContext.Current.ToRequestContext ().Get<IHttpRequest>()).ReusedWithin(Funq.ReuseScope.None);

Now, I am always getting the IHttpRequest object I am supposed to when I try to resolve them.

Also, after more thourough tests in my application I was able to detect that everything that was relying on registering with ReuseScope.Request was getting mixed up if the concurrency was high enough.

The solution was quite simple, I am relying now on the HttpContext.Current.Items collection for storing these request-specific dependencies and registering them on a request filter like this:

        HttpContext.Current.Items ["Token"] = token;
        container.Register<Token> (c =>  (Token)HttpContext.Current.Items["Token"]).ReusedWithin(Funq.ReuseScope.None);

Now it works as it was supposed to every time.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top