C# OWIN网络API+;OWIN测试服务器+;Ninject依赖项注入

C# OWIN网络API+;OWIN测试服务器+;Ninject依赖项注入,c#,testing,asp.net-web-api2,ninject,owin,C#,Testing,Asp.net Web Api2,Ninject,Owin,从高层角度来看,我想使用OWIN测试服务器对我创建的Web API控制器执行集成测试。我大致上遵循了本教程。下面是技术堆栈概述 OWIN Microsoft.Owin.Host.SystemWeb Microsoft.OWIN.Testing 用于自托管的其他Owin组件 Ninject public partial class Startup { #region Ninject Dependency Injection private static IKernel _con

从高层角度来看,我想使用OWIN测试服务器对我创建的Web API控制器执行集成测试。我大致上遵循了本教程。下面是技术堆栈概述

OWIN

  • Microsoft.Owin.Host.SystemWeb
  • Microsoft.OWIN.Testing
  • 用于自托管的其他Owin组件
Ninject

public partial class Startup
{
    #region Ninject Dependency Injection
    private static IKernel _container { get; set; }
    public static IKernel Container
    {
        get
        {
            if (UseUnitTestKernel)
            {
                return _container;
            }

            throw new Exception("Startup has not been designated to use integration test dependeny injection");
        }
    }
    public static bool UseUnitTestKernel { get; set; }
    #endregion Ninject Dependency Injection

    public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

    public static string PublicClientId { get; private set; }

    //Save off _app builder in case we want to retrieve a value later
    private static IAppBuilder _app;


 /// <summary>
    /// Bootstrap application
    /// </summary>
    /// <param name="app"></param>
    public void Configuration(IAppBuilder app)
    {
        _app = app;
        ConfigureAuth(app);

        if (!UseUnitTestKernel)
        {
            app.UseNinjectMiddleware(NinjectWebApiKernel.CreateKernel);
            app.UseNinjectWebApi(ConfigWebAPI());
        }
        else
        {
            app.UseWebApi(ConfigWebAPIForIntegrationTesting());
        }
    }

        /// <summary>
    /// Configure authorization
    /// </summary>
    /// <param name="app"></param>
    public void ConfigureAuth(IAppBuilder app)
    {
        PublicClientId = "JustBlogWeb";

        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            AuthorizeEndpointPath = new PathString("/Account/Authorize"),
            Provider = new ApplicationOAuthProvider(PublicClientId),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            AllowInsecureHttp = true
        };

        // Enable the application to use a cookie to store information for the signed in user
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                // Enables the application to validate the security stamp when the user logs in.
                // This is a security feature which is used when you change a password or add an external login to your account.  
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(20),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });




        // Configure the db context, user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
    }

        /// <summary>
    /// Setup WebAPI routes
    /// </summary>
    /// <returns></returns>
    private HttpConfiguration ConfigWebAPI()
    {
        HttpConfiguration config = new HttpConfiguration();

        // Web API configuration and services
        //Must have this on to view errors;
        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        config.EnableSwagger(c => c.SingleApiVersion("v1", "Just Blog API")).EnableSwaggerUi();

        return config;
    }

    /// <summary>
    /// Configure Web API for integration testing
    /// </summary>
    /// <returns></returns>
    private HttpConfiguration ConfigWebAPIForIntegrationTesting()
    {
        HttpConfiguration config = new HttpConfiguration();

        // Web API configuration and services
        //Must have this on to view errors;
        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        _container = new StandardKernel();
        _container.Bind<DefaultModelValidatorProviders>()
                        .ToConstant(new DefaultModelValidatorProviders(
                                config.Services.GetServices(typeof(ModelValidatorProvider)).Cast<ModelValidatorProvider>()));

        _container.Bind<DefaultFilterProviders>()
            .ToConstant(new DefaultFilterProviders(
                    config.Services.GetServices(typeof(IFilterProvider)).Cast<DefaultFilterProvider>()));

        //_container.Bind(x => x.FromThisAssembly().SelectAllClasses().BindAllInterfaces());
        _container.Bind<IPostService>().To<PostService>();
        config.DependencyResolver =  new NinjectUnitTestDependencyResolver(_container);

        return config;
    }
    /// <summary>
/// Static class for generating a Web API Ninject Kernel
/// </summary>
public static class NinjectWebApiKernel
{
    //List of Mocked Services
    public static IDictionary<Type, Mock> Mocks;

    /// <summary>
    /// Create kernel bindings for IoC and Dependency Injection
    /// </summary>
    /// <returns></returns>
    public static IKernel CreateKernel()
    {
        IKernel kernel = new StandardKernel();
        kernel.Load(Assembly.GetExecutingAssembly());
        RegisterServices(kernel);

        //Rebind mocked services if we have any
        // TODO Remove rebind and extraneous ninject rules
        //RebindToConfiguredMocks(_container, Mocks);
        return kernel;
    }

    /// <summary>
    /// Register ninject services
    /// </summary>
    /// <param name="kernel"></param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IAuthProvider>().To<AuthProvider>();
        kernel.Bind<IJustBlogContext>().To<JustBlogContext>();

        kernel.Bind<IPostService>().To<PostService>();
        kernel.Bind<ICategoryService>().To<CategoryService>();
        kernel.Bind<ITagService>().To<TagService>();
    }

    /// <summary>
    /// Rebind all mocked services for dependency injection
    /// </summary>
    private static void RebindToConfiguredMocks(IKernel kernel, IDictionary<Type, Mock> mocks)
    {
        foreach (var item in mocks)
        {
            kernel.Unbind(item.Key);
            var item1 = item;
            kernel.Bind(item.Key).ToMethod(_ => mocks[item1.Key].Object);
        }
    }

}

/// <summary>
/// Ninject Unit Testing Dependency resolver. We use this dependency resolver
/// for unit testing
/// </summary>
public class NinjectUnitTestDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver
{
    protected IResolutionRoot Container;

    public NinjectUnitTestDependencyResolver(IKernel container)
    {
        Container = container;
    }

    public NinjectUnitTestDependencyResolver(IResolutionRoot container)
    {
        Container = container;
    }

    public object GetService(Type serviceType)
    {
        return Container.TryGet(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return Container.GetAll(serviceType);
    }

    public IDependencyScope BeginScope()
    {
        if (!(Container is IKernel))
        {
            throw new NotImplementedException("Can't begin a scope on a scope");
        }

        return new NinjectUnitTestDependencyResolver(((IKernel)Container).BeginBlock());
    }

    public void Dispose()
    {
    }
}
    public class PostController_Tests
{
    private TestServer _server;
    private const string _baseServerURL = "http://testserver";
    private IDictionary<Type, Mock> _mocks;

    /// <summary>
    /// Integration test for the Post Controller "UnitTest" endpoint
    /// </summary>
    /// <returns></returns>
    [TestMethod]
    public async Task PostController_UnitTest_Test()
    {
        string endPoint = $"{_baseServerURL}/{RoutePrefixes.RESOURCE_POST}/{nameof(PostController.UnitTest)}";

        HttpResponseMessage response = await _server.HttpClient.GetAsync(endPoint);

        string content = await response.Content.ReadAsStringAsync();
        Assert.AreEqual(content, "true");
    }

    /// <summary>
    /// Test the retrieval of a post by url tag
    /// </summary>
    /// <returns></returns>
    [TestMethod]
    public async Task RetrievePost_By_UrlTag_Test()
    {
        string endPoint = GenerateAPIEndpoint(RoutePrefixes.RESOURCE_POST, nameof(PostController.Retrieve));

        var postSet_Mock = new Mock<DbSet<Post>>();

        var justBlogContext_Mock = new Mock<JustBlogContext>();
        justBlogContext_Mock.Setup(m => m.Posts).Returns(postSet_Mock.Object);

        IPostService postService = new PostService(justBlogContext_Mock.Object);

        MockOut<IPostService>().Setup(x => x.Post(It.IsAny<string>())).Returns(new PostViewModel());

        HttpResponseMessage response = await _server.HttpClient.GetAsync(endPoint);
        PostViewModel result = await response.Content.ReadAsAsync<PostViewModel>();
    }

    /// <summary>
    /// Run after the entire test class runs
    /// </summary>
    [TestInitialize()]
    public void ServerInit()
    {
        _mocks = new ConcurrentDictionary<Type, Mock>();
        Startup.UseUnitTestKernel = true;

        _server = TestServer.Create<Startup>();

        var test = Startup.GetTestKernel();
    }

    /// <summary>
    /// Run before each class is initialized
    /// </summary>
    /// <param name="context"></param>
    [TestCleanup()]
    public void ServerDispose()
    {
        _server.Dispose();
    }

    #region Private Methods and Classes

    /// <summary>
    /// Generate the API endpoint for a controller method
    /// </summary>
    /// <param name="controllerName"></param>
    /// <param name="methodName"></param>
    /// <returns></returns>
    protected string GenerateAPIEndpoint(string controllerName, string methodName)
    {
        return $"{_baseServerURL}/{controllerName}/{methodName}";
    }

    /// <summary>
    /// Create a new mocked service
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    protected Mock<T> MockOut<T>() where T :class
    {
        if (_mocks.ContainsKey(typeof(T)))
        {
            RebindToConfiguredMocks();
            return (Mock<T>)_mocks[typeof(T)];
        }

        _mocks.Add(typeof(T), new Mock<T>());
        RebindToConfiguredMocks();

        return (Mock<T>)_mocks[typeof(T)];
    }

    /// <summary>
    /// Rebind all mocked services for dependency injection
    /// </summary>
    protected void RebindToConfiguredMocks()
    {
        foreach(var item in _mocks)
        {
            Startup.Container.Unbind(item.Key);
            var item1 = item;
            Startup.Container.Bind(item.Key).ToMethod(_ => _mocks[item1.Key].Object);
        }
    }

    #endregion Private Methods and Classes
}
  • Ninject.Web.WebAPI.OwinHost
  • 其他相关的Ninject Web API组件
Moq

  • 用于模拟控制器中的服务类
整个应用程序功能非常好—Web API控制器+OWIN+Ninject,但是当我使用OWIN测试服务器创建集成测试时,我还没有找到重新绑定模拟服务的方法。这是由于Ninject服务提供者的缘故——Ninject内核的作用域是基于每个请求设置的,因此我无法将模拟服务重新绑定到请求

我发现了一种解决这个问题的方法(请参见下面的ConfigWebAPIForIntegrationTesting()),即在Http配置上设置依赖项解析器,而不是使用Ninject Owin扩展UseNinjectWebApi()。这将非常有效,但当我实现这一点时,Ninject似乎无法像正常使用UseNinjectWebAPI时那样获取Web API绑定

在这一点上,我被卡住了。在一个充满阳光和彩虹的世界中,我希望能够在我的测试项目中创建集成测试,使用具体实现中的OWIN Startup.cs并根据需要交换业务逻辑服务类。有没有人有任何经验或建议来纠正我的依赖注入问题并成功地对我的WebAPI端点进行单元测试

在此问题上,非常感谢您的帮助

Startup.cs-在Blog.UI项目中

public partial class Startup
{
    #region Ninject Dependency Injection
    private static IKernel _container { get; set; }
    public static IKernel Container
    {
        get
        {
            if (UseUnitTestKernel)
            {
                return _container;
            }

            throw new Exception("Startup has not been designated to use integration test dependeny injection");
        }
    }
    public static bool UseUnitTestKernel { get; set; }
    #endregion Ninject Dependency Injection

    public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

    public static string PublicClientId { get; private set; }

    //Save off _app builder in case we want to retrieve a value later
    private static IAppBuilder _app;


 /// <summary>
    /// Bootstrap application
    /// </summary>
    /// <param name="app"></param>
    public void Configuration(IAppBuilder app)
    {
        _app = app;
        ConfigureAuth(app);

        if (!UseUnitTestKernel)
        {
            app.UseNinjectMiddleware(NinjectWebApiKernel.CreateKernel);
            app.UseNinjectWebApi(ConfigWebAPI());
        }
        else
        {
            app.UseWebApi(ConfigWebAPIForIntegrationTesting());
        }
    }

        /// <summary>
    /// Configure authorization
    /// </summary>
    /// <param name="app"></param>
    public void ConfigureAuth(IAppBuilder app)
    {
        PublicClientId = "JustBlogWeb";

        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            AuthorizeEndpointPath = new PathString("/Account/Authorize"),
            Provider = new ApplicationOAuthProvider(PublicClientId),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            AllowInsecureHttp = true
        };

        // Enable the application to use a cookie to store information for the signed in user
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                // Enables the application to validate the security stamp when the user logs in.
                // This is a security feature which is used when you change a password or add an external login to your account.  
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(20),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });




        // Configure the db context, user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
    }

        /// <summary>
    /// Setup WebAPI routes
    /// </summary>
    /// <returns></returns>
    private HttpConfiguration ConfigWebAPI()
    {
        HttpConfiguration config = new HttpConfiguration();

        // Web API configuration and services
        //Must have this on to view errors;
        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        config.EnableSwagger(c => c.SingleApiVersion("v1", "Just Blog API")).EnableSwaggerUi();

        return config;
    }

    /// <summary>
    /// Configure Web API for integration testing
    /// </summary>
    /// <returns></returns>
    private HttpConfiguration ConfigWebAPIForIntegrationTesting()
    {
        HttpConfiguration config = new HttpConfiguration();

        // Web API configuration and services
        //Must have this on to view errors;
        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        _container = new StandardKernel();
        _container.Bind<DefaultModelValidatorProviders>()
                        .ToConstant(new DefaultModelValidatorProviders(
                                config.Services.GetServices(typeof(ModelValidatorProvider)).Cast<ModelValidatorProvider>()));

        _container.Bind<DefaultFilterProviders>()
            .ToConstant(new DefaultFilterProviders(
                    config.Services.GetServices(typeof(IFilterProvider)).Cast<DefaultFilterProvider>()));

        //_container.Bind(x => x.FromThisAssembly().SelectAllClasses().BindAllInterfaces());
        _container.Bind<IPostService>().To<PostService>();
        config.DependencyResolver =  new NinjectUnitTestDependencyResolver(_container);

        return config;
    }
    /// <summary>
/// Static class for generating a Web API Ninject Kernel
/// </summary>
public static class NinjectWebApiKernel
{
    //List of Mocked Services
    public static IDictionary<Type, Mock> Mocks;

    /// <summary>
    /// Create kernel bindings for IoC and Dependency Injection
    /// </summary>
    /// <returns></returns>
    public static IKernel CreateKernel()
    {
        IKernel kernel = new StandardKernel();
        kernel.Load(Assembly.GetExecutingAssembly());
        RegisterServices(kernel);

        //Rebind mocked services if we have any
        // TODO Remove rebind and extraneous ninject rules
        //RebindToConfiguredMocks(_container, Mocks);
        return kernel;
    }

    /// <summary>
    /// Register ninject services
    /// </summary>
    /// <param name="kernel"></param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IAuthProvider>().To<AuthProvider>();
        kernel.Bind<IJustBlogContext>().To<JustBlogContext>();

        kernel.Bind<IPostService>().To<PostService>();
        kernel.Bind<ICategoryService>().To<CategoryService>();
        kernel.Bind<ITagService>().To<TagService>();
    }

    /// <summary>
    /// Rebind all mocked services for dependency injection
    /// </summary>
    private static void RebindToConfiguredMocks(IKernel kernel, IDictionary<Type, Mock> mocks)
    {
        foreach (var item in mocks)
        {
            kernel.Unbind(item.Key);
            var item1 = item;
            kernel.Bind(item.Key).ToMethod(_ => mocks[item1.Key].Object);
        }
    }

}

/// <summary>
/// Ninject Unit Testing Dependency resolver. We use this dependency resolver
/// for unit testing
/// </summary>
public class NinjectUnitTestDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver
{
    protected IResolutionRoot Container;

    public NinjectUnitTestDependencyResolver(IKernel container)
    {
        Container = container;
    }

    public NinjectUnitTestDependencyResolver(IResolutionRoot container)
    {
        Container = container;
    }

    public object GetService(Type serviceType)
    {
        return Container.TryGet(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return Container.GetAll(serviceType);
    }

    public IDependencyScope BeginScope()
    {
        if (!(Container is IKernel))
        {
            throw new NotImplementedException("Can't begin a scope on a scope");
        }

        return new NinjectUnitTestDependencyResolver(((IKernel)Container).BeginBlock());
    }

    public void Dispose()
    {
    }
}
    public class PostController_Tests
{
    private TestServer _server;
    private const string _baseServerURL = "http://testserver";
    private IDictionary<Type, Mock> _mocks;

    /// <summary>
    /// Integration test for the Post Controller "UnitTest" endpoint
    /// </summary>
    /// <returns></returns>
    [TestMethod]
    public async Task PostController_UnitTest_Test()
    {
        string endPoint = $"{_baseServerURL}/{RoutePrefixes.RESOURCE_POST}/{nameof(PostController.UnitTest)}";

        HttpResponseMessage response = await _server.HttpClient.GetAsync(endPoint);

        string content = await response.Content.ReadAsStringAsync();
        Assert.AreEqual(content, "true");
    }

    /// <summary>
    /// Test the retrieval of a post by url tag
    /// </summary>
    /// <returns></returns>
    [TestMethod]
    public async Task RetrievePost_By_UrlTag_Test()
    {
        string endPoint = GenerateAPIEndpoint(RoutePrefixes.RESOURCE_POST, nameof(PostController.Retrieve));

        var postSet_Mock = new Mock<DbSet<Post>>();

        var justBlogContext_Mock = new Mock<JustBlogContext>();
        justBlogContext_Mock.Setup(m => m.Posts).Returns(postSet_Mock.Object);

        IPostService postService = new PostService(justBlogContext_Mock.Object);

        MockOut<IPostService>().Setup(x => x.Post(It.IsAny<string>())).Returns(new PostViewModel());

        HttpResponseMessage response = await _server.HttpClient.GetAsync(endPoint);
        PostViewModel result = await response.Content.ReadAsAsync<PostViewModel>();
    }

    /// <summary>
    /// Run after the entire test class runs
    /// </summary>
    [TestInitialize()]
    public void ServerInit()
    {
        _mocks = new ConcurrentDictionary<Type, Mock>();
        Startup.UseUnitTestKernel = true;

        _server = TestServer.Create<Startup>();

        var test = Startup.GetTestKernel();
    }

    /// <summary>
    /// Run before each class is initialized
    /// </summary>
    /// <param name="context"></param>
    [TestCleanup()]
    public void ServerDispose()
    {
        _server.Dispose();
    }

    #region Private Methods and Classes

    /// <summary>
    /// Generate the API endpoint for a controller method
    /// </summary>
    /// <param name="controllerName"></param>
    /// <param name="methodName"></param>
    /// <returns></returns>
    protected string GenerateAPIEndpoint(string controllerName, string methodName)
    {
        return $"{_baseServerURL}/{controllerName}/{methodName}";
    }

    /// <summary>
    /// Create a new mocked service
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    protected Mock<T> MockOut<T>() where T :class
    {
        if (_mocks.ContainsKey(typeof(T)))
        {
            RebindToConfiguredMocks();
            return (Mock<T>)_mocks[typeof(T)];
        }

        _mocks.Add(typeof(T), new Mock<T>());
        RebindToConfiguredMocks();

        return (Mock<T>)_mocks[typeof(T)];
    }

    /// <summary>
    /// Rebind all mocked services for dependency injection
    /// </summary>
    protected void RebindToConfiguredMocks()
    {
        foreach(var item in _mocks)
        {
            Startup.Container.Unbind(item.Key);
            var item1 = item;
            Startup.Container.Bind(item.Key).ToMethod(_ => _mocks[item1.Key].Object);
        }
    }

    #endregion Private Methods and Classes
}
公共部分类启动
{
#区域对象依赖注入
私有静态IKernel_容器{get;set;}
公共静态IKernel容器
{
得到
{
if(UseUnitTestKernel)
{
返回容器;
}
抛出新异常(“启动未被指定为使用集成测试依赖注入”);
}
}
公共静态bool UseUnitTestKernel{get;set;}
#endregion对象依赖项注入
公共静态OAuthAuthorizationServerOptions OAuthOptions{get;private set;}
公共静态字符串PublicClientId{get;private set;}
//保存应用程序生成器,以防以后要检索值
私有静态IAppBuilder(应用程序);
/// 
///引导应用程序
/// 
/// 
公共无效配置(IAppBuilder应用程序)
{
_app=app;
ConfigureAuth(app);
如果(!UseUnitTestKernel)
{
app.usenjectMiddleware(ninjectwebapickernel.CreateKernel);
app.UseNinjectWebApi(ConfigWebAPI());
}
其他的
{
app.UseWebApi(ConfigWebAPIForIntegrationTesting());
}
}
/// 
///配置授权
/// 
/// 
public void ConfigureAuth(IAppBuilder应用程序)
{
PublicClientId=“JustBlogWeb”;
OAuthOptions=新的OAuthAuthorizationServerOptions
{
TokenEndpointPath=新路径字符串(“/Token”),
AuthorizeEndpointPath=新路径字符串(“/Account/Authorize”),
Provider=新的ApplicationAuthProvider(PublicClientId),
AccessTokenExpireTimeSpan=TimeSpan.FromDays(14),
AllowInsecureHttp=true
};
//使应用程序能够使用cookie存储登录用户的信息
app.UseCookieAuthentication(新的CookieAuthenticationOptions
{
AuthenticationType=DefaultAuthenticationTypes.ApplicationOkie,
LoginPath=新路径字符串(“/Account/Login”),
Provider=新CookieAuthenticationProvider
{
//允许应用程序在用户登录时验证安全戳。
//这是一种安全功能,在您更改密码或向帐户添加外部登录时使用。
OnValidateIdentity=SecurityStampValidator.OnValidateIdentity(
validateInterval:TimeSpan.FromMinutes(20),
regenerateIdentity:(管理器,用户)=>user.GenerateUserIdentityAsync(管理器))
}
});
//将数据库上下文、用户管理器和登录管理器配置为每个请求使用一个实例
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext(ApplicationUserManager.Create);
app.CreatePerOwinContext(ApplicationSignInManager.Create);
}
/// 
///设置WebAPI路由
/// 
/// 
私有HttpConfiguration ConfigWebAPI()
{
HttpConfiguration config=新的HttpConfiguration();
//Web API配置和服务
//必须打开此选项才能查看错误;
config.IncludeErrorDetailPolicy=IncludeErrorDetailPolicy.Always;
//Web API路由
config.maphttpAttribute路由();
config.Routes.MapHttpRoute(
名称:“DefaultApi”,
routeTemplate:“api/{controller}/{id}”,
默认值:新建{id=RouteParameter.Optional}
);
config.EnableSwagger(c=>c.SingleApiVersion(“v1”,“Just Blog API”)).EnableSwaggerUi();
返回配置;
}
/// 
///为集成测试配置Web API
/// 
/// 
私有HttpConfiguration ConfigWebAPIForIntegrationTesting()
{
HttpConfiguration config=新的HttpConfiguration();
//Web API配置和服务
//必须打开此选项才能查看错误;
config.Includ