Ninject, WebAPI and ExceptionFilterAttribute being called twice
Asked Answered
S

1

7

Good morning all,

I noticed strange behavior of Ninject (at least I think that it is the problem) in my project. The situation is the following. I use

Ninject.3.0.2-unstable-9028
Ninject.Extensions.Factory.3.0.1.0
Ninject.Web.Common.3.0.2-unstable-9012
Ninject.Web.WebApi-RC.3.0.0.22

I changed the NinjectWebCommon.cs and added code with my bindings. I have a WebApiConfig.cs which configures global exceptions handler

public static void Register(HttpConfiguration config)
{
    // Authentication token handler.
    config.MessageHandlers.Add(new TokenAuthenticationHandler());

    // Exceptions handler.
    config.Filters.Add(new ExceptionsHandler());
    ...
 }

and I have an exceptions handler class

public class ExceptionsHandler : ExceptionFilterAttribute
{
    ...
    public override void OnException(HttpActionExecutedContext context)
    {

        ...
        context.Response = context.Request.CreateErrorResponse(httpStatusCode, response);
    }
}

Now, when the request comes to the API it first gets to TokenAuthenticationHandler() object which does its magic and calls

return base.SendAsync(request, cancellationToken);

Then WebAPI controller kicks in and does its magic. In case of exception, it gets thrown and OnException of ExceptionsHandler gets called. The problem is that when OnException finishes its job, It gets called again with same context and I can't find the reason why.

I don't configure it twice. I don't have extra records in web.config. It started happening when I started using Ninject.Web.WebAPI-RC library. Before that I was using custom made Resolvers and Contexts classes that worked well, but, didn't dispose Ninject created objects. So, I decided to use what works. And everything do work except that for some reason OnException gets called twice.

If I remove

config.Filters.Add(new ExceptionsHandler());

from WebApiConfig.cs then it doesn't get called at all.

I think that Ninject has something to do with it, but I can't understand why it happens.

Thank you in advance.

Serles answered 18/2, 2014 at 23:14 Comment(4)
I suggest you to not use Ninject.Web.WebAPI-RC as time of writing. It is not stable, you should stick with the code you had before. IF you need to perform DI for your filters, check this out: #21614639Pesthole
The problem with code I was using before is that extensions like InScopeRequest() weren't working. Objects created by Ninject weren't disposed correctly after the request to the Web API controller was done.Serles
Which DependencyResolver were you using? Check this implementation, I think you'd be okay with that gist.github.com/cvbarros/8783363Pesthole
Thank you. I was using the following peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api classes. I have tried using ones provided by you. I have also removed Ninject.Web.WebAPI from my references and started using only stable versions Ninject, Ninject.Web.Common but now my InRequestScope objects are not getting disposed when the request is finished as well as properties with [Inject] attributes are not getting populated. I think I will live with what I had before until I will find a solution... Thank you.Serles
M
9

try this

 [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
 public class ExceptionsHandler : ExceptionFilterAttribute
 {
    ...
    public override void OnException(HttpActionExecutedContext context)
    {

      ...
       context.Response = context.Request.CreateErrorResponse(httpStatusCode, response);
    }
 }

This worked for me.. =)

Moulder answered 30/4, 2014 at 15:59 Comment(2)
This worked for me. I think the exception was handled by controller and action too.Johnston
It worked like magic. But I still don't understand why it works. By default, ExceptionFilterAttribute is has attribusage to .Class and .Method, which would cover controller and action. What does .All actually enable that is not covered otherwise?Preoccupation

© 2022 - 2024 — McMap. All rights reserved.