Asp.Net API 2 Ninject和OWIN OAuth配置

时间:2015-12-14 22:58:37

标签: c# asp.net-web-api ninject owin

我知道有很多帖子与这个帖子非常相似。但是,我已经通过它们并且无法找到解决问题的方法。

我正在使用OWIN将OAth身份验证实现到以前使用Ninject进行依赖注入的项目中。

使用OWIN从原始的Global.asax Application_Start配置方法切换到创建用于配置OWIN的Start.cs文件/类来实现OATH。

我面临的问题是无论我尝试运行代码的是什么实现,API请求总是返回错误"确保控制器具有无参数的公共构造函数"。

请问有人能说明以下两种方法都不起作用的原因吗?

我解决问题的第一个尝试是将app.UseNinjectMiddleware与app.UseNinjectWebApi一起使用。其次,我尝试了NinjectDependencyResolver,这在之前的许多帖子中都有提及。 Link to similar post

下面是两个实现的代码。

public class Startup
{
    public void Configuration( IAppBuilder app )
    {
        var config = new HttpConfiguration();
        var kernel = NinjectWebCommon.CreateKernel();

        // Using this and UseNinjectWebAPI
        app.UseNinjectMiddleware( () => kernel );

        ConfigureOAuthTokenGeneration( app );
        ConfigureWebApi( config );

        app.UseCors( Microsoft.Owin.Cors.CorsOptions.AllowAll );

        WebApiConfig.Register( config );
        app.UseNinjectWebApi( config );

        // Also tried this ( when the following lines are uncommented UseNinjectMiddleware and useNinjectWebApi is commented )
        // This causes "Make sure that the controller has a parameterless public constructor" error
        //GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver( kernel );
        //app.UseWebApi( config );
    }

    private void ConfigureOAuthTokenGeneration( IAppBuilder app )
    {
        // Configure the db context and user manager to use a single instance per request
        app.CreatePerOwinContext( ApplicationDbContext.Create );
        app.CreatePerOwinContext<ApplicationUserManager>( ApplicationUserManager.Create );

        // Plugin the OAuth bearer JSON Web Token tokens generation and Consumption will be here

    }

    private void ConfigureWebApi( HttpConfiguration config )
    {
        var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
        jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    }
}

这是我的NinjectWebCommon类

//[assembly:     WebActivatorEx.PreApplicationStartMethod(typeof(TimeUp.Web.Api.App_Start.NinjectWebCommon), "Start")]
//[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(TimeUp.Web.Api.App_Start.NinjectWebCommon), "Stop")]

namespace Shopping
{
    public static class NinjectWebCommon
    {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        /// <summary>
        /// Starts the application
        /// </summary>
        public static void Start()
        {
            DynamicModuleUtility.RegisterModule( typeof( OnePerRequestHttpModule ) );
            DynamicModuleUtility.RegisterModule( typeof( NinjectHttpModule ) );
            bootstrapper.Initialize( CreateKernel );
        }

        /// <summary>
        /// Stops the application.
        /// </summary>
        public static void Stop()
        {
            bootstrapper.ShutDown();
        }

        /// <summary>
        /// Creates the kernel that will manage your application.
        /// </summary>
        /// <returns>The created kernel.</returns>
        public static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            try
            {
                kernel.Bind<Func<IKernel>>().ToMethod( ctx => () => new Bootstrapper().Kernel );
                kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

                RegisterServices( kernel );

                return kernel;
            }
            catch
            {
                kernel.Dispose();
                throw;
            }
        }

        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices( IKernel kernel )
        {
        }
    }
}

先谢谢

1 个答案:

答案 0 :(得分:0)

我终于解决了问题,解决方案是使用Ninject.Web.Common库附带的原始NinjectWebCommon类。此类的start方法在Startup.Configuration之前触发,因此可以通过引导程序将其退出,以便与此Dependency Resolver一起使用。这是我的工作配置。

    public void Configuration( IAppBuilder app )
    {
        var config = new HttpConfiguration();

        config.DependencyResolver = new NinjectResolver( new Ninject.Web.Common.Bootstrapper().Kernel );
        WebApiConfig.Register( config );

        app.UseWebApi( config );
    }