asp.net-web-apidependency-injectionninjectnotimplementedexception

Ninject causes NotImplementedException at HttpContextBase.get_Response()


I'm building an ASP.NET Web API 2 project. I wanted to use dependency injection so I installed the Ninject Library for the purpose.

At first, I tried to install it by using the NuGet Package Manager, but I got the following error upon installation:

Install failed. Rolling back...
Updating 'Microsoft.Owin 3.0.0' to 'Microsoft.Owin 2.0.0' failed. 
Unable to find versions of 'Microsoft.Owin.Security,
Microsoft.Owin.Security.Cookies, Microsoft.Owin.Security.OAuth, 
Microsoft.AspNet.WebApi.Owin, Microsoft.Owin.Host.SystemWeb, 
Microsoft.Owin.Security.Facebook, Microsoft.Owin.Security.Google, 
Microsoft.Owin.Security.MicrosoftAccount, Microsoft.Owin.Security.Twitter'
that are compatible with 'Microsoft.Owin 2.0.0'.

I then, followed the instructions in this post that suggest running the following command in the NuGet Package Manager Console:

Install-Package Ninject.Web.WebApi.OwinHost -Version 3.2.1 -DependencyVersion Highest

After entering this command, the package installed successfully.

This is the configuration of Ninject, which I set, following the instructions in this Ninject GitHub post.

    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);

        app.UseNinjectMiddleware(CreateKernel).UseNinjectWebApi(GlobalConfiguration.Configuration);
    }

    private static StandardKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Load(Assembly.GetExecutingAssembly());
        return kernel;
    }

Here's where the problem occurs. I want to use the CreatedAtRoute() method in some of my controllers.

return CreatedAtRoute("GetMyResourceByIdRoute",
            new { id = myResource.Id },
            myResource);

When I make a call to the method, that uses CreatedAtRoute() I get the following exception:

System.NotImplementedException

Stack trace: at System.Web.HttpContextBase.get_Response()\r\n   
at System.Web.UI.Util.GetUrlWithApplicationPath(HttpContextBase context, 
String url)\r\n   at System.Web.Routing.RouteCollection.NormalizeVirtualPath
(RequestContext requestContext, String virtualPath)\r\n   at 
System.Web.Routing.RouteCollection.GetVirtualPath(RequestContext 
requestContext, String name, RouteValueDictionary values)\r\n   at 
System.Web.Http.WebHost.Routing.HostedHttpRouteCollection.GetVirtualPath
(HttpRequestMessage request, String name, IDictionary`2 values)\r\n   at 
System.Web.Http.Routing.UrlHelper.GetVirtualPath(HttpRequestMessage request, String routeName, IDictionary`2 routeValues)\r\n   at 
System.Web.Http.Routing.UrlHelper.Route(String routeName, IDictionary`2 routeValues)\r\n   at 
System.Web.Http.Routing.UrlHelper.Link(String routeName, IDictionary`2 routeValues)\r\n   at 
System.Web.Http.Results.CreatedAtRouteNegotiatedContentResult`1.Execute()\r\n   at 
System.Web.Http.Results.CreatedAtRouteNegotiatedContentResult`1.ExecuteAsync(CancellationToken cancellationToken)\r\n   at 
System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at 
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at 
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at 
System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n
--- End of stack trace from previous location where exception was thrown 
---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at 
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at 
System.Web.Http.Controllers.AuthenticationFilterResult.<ExecuteAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at 
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at 
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at 
System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()

I concluded that there's some problem with my Ninject configuration just because when I comment out

app.UseNinjectMiddleware(CreateKernel).UseNinjectWebApi(GlobalConfiguration.Configuration);

from my Configuration method, everything works fine.

So, does anybody have any idea what is wrong and how I can fix this?


Solution

  • I stumbled upon the same problem with the NotImplementedException when trying to compose a link with this.Url.Link("DefaultApi", new { controller="controller_name", id = "some_id" })

    It turned out Web API was not configured correctly. The key is to use a completely different HttpConfiguration, and not the global one:

      // initialize web pages & mvc routing first
      AreaRegistration.RegisterAllAreas();
      ConfigureRoutes(RouteTable.Routes);
      BundleConfig.RegisterBundles(BundleTable.Bundles);
    
      // set up IOC and configure authentication
      app.UseNinjectMiddleware(CreateKernel);
      ConfigureAuth(app);
    
      // finally the web api, on its own http configuration
      var webApiConfig = new HttpConfiguration();
      webApiConfig.MapHttpAttributeRoutes();
      webApiConfig.Routes.MapHttpRoute(
        name: "DefaultApi", 
        routeTemplate:api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional });
      app.UseNinjectWebApi(webApiConfig);
    
      // ensure all the configs are ready
      webApiConfig.EnsureInitialized();
      GlobalConfiguration.Configuration.EnsureInitialized();
    

    Make sure you got the latest OWIN packages, including Ninject.Web.Common.OwinHost and Ninject.Web.WebApi.OwinHost.