Ninject 在 HttpContextBase.get_Response() 处导致 NotImplementedException

Ninject causes NotImplementedException at HttpContextBase.get_Response()

我正在构建一个 ASP.NET Web API 2 项目。我想使用依赖注入,所以我为此安装了 Ninject 库。

起初,我尝试使用 NuGet 包管理器安装它,但安装时出现以下错误:

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'.

然后,我按照 this post 中的说明进行操作,该说明建议 运行 在 NuGet 程序包管理器控制台中执行以下命令:

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

输入此命令后,包安装成功。

这是Ninject的配置,我按照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;
    }

问题出在这里。我想在我的一些控制器中使用 CreatedAtRoute() 方法。

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

当我调用使用 CreatedAtRoute() 的方法时,出现以下异常:

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()

我的结论是我的 Ninject 配置有问题,因为当我注释掉

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

从我的配置方法来看,一切正常。

所以,有人知道哪里出了问题以及我该如何解决这个问题吗?

我在尝试用 this.Url.Link("DefaultApi", new { controller="controller_name", id = "some_id" })

组合 link 时偶然发现了与 NotImplementedException 相同的问题

原来 Web API 配置不正确。关键是要使用完全不同的 HttpConfiguration,而不是全局的:

  // 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();

确保您获得了最新的 OWIN 软件包,包括 Ninject.Web.Common.OwinHostNinject.Web.WebApi.OwinHost