为ASP.Net WebAPI应用程序配置ASP.Net标识

时间:2016-05-07 13:18:45

标签: asp.net asp.net-web-api asp.net-identity owin

我有一个以前允许匿名访问的SPA ASP.NET WebAPI应用程序。我现在已经为它配置了ASP.Net Identity但我无法让Identity相关的控制器和我的应用程序的其他控制器同时工作:-( 它是一个或另一个!

我已将启动类添加到我的项目中:

using Test.MyProject;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.DataHandler.Encoder;
using Microsoft.Owin.Security.OAuth;
using Newtonsoft.Json.Serialization;
using Owin;
using System;
using System.Configuration;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web.Http;

[assembly: OwinStartup(typeof(Test.Client.Startup))]
namespace Test.Client
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            HttpConfiguration httpConfig = new HttpConfiguration();

            ConfigureOAuthTokenGeneration(app);

            ConfigureWebApi(httpConfig);

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

            //app.UseWebApi(httpConfig);  // If this line is commented out my application's controllers work. But then my Account Controller does't work. It if is included, my application's controllers don't work, whilst the Account Controller work

            GlobalConfiguration.Configure(WebApiConfig.Register);
        }

        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);
        }

        private void ConfigureWebApi(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
            jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        }
    }
}

我添加了用于管理用户和角色的控制器。 语句GlobalConfiguration.Configure(WebApiConfig.Register)之前在global.aspx.cs中的应用程序启动事件中,但现在已转移到启动类以使所有内容都在同一位置。

WebApiConfig.Register方法如下所示:

public static void Register(HttpConfiguration config)
{
    var container = new UnityContainer();
    // Web API configuration and services

    string appStorageProvider = ConfigurationManager.AppSettings["StorageProvider"];
    var provider =(TestComposition.StorageProvider) Enum.Parse(typeof (TestComposition.StorageProvider), appStorageProvider, true);

    TestComposition.Setup(container, provider);
    container.RegisterType<GeneralLogger, GeneralLogger>();

    container.RegisterType<IExceptionLogger, ExceptionLogger>();

    config.EnableCors();

    config.DependencyResolver = new UnityResolver(container);
    config.Services.Add(typeof (IExceptionLogger), container.Resolve<GeneralLogger>());

    // Web API routes
    config.MapHttpAttributeRoutes();
}

在我的新AccountController我有代码,可以让我从Startup类中的ApplicationUserManager设置中检索OwinContext

protected ApplicationUserManager AppUserManager
{
    get
    {
        return _AppUserManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
    }
}

如上所示注释app.UseWebApi(httpConfig),我的应用程序就像以前一样工作。但是如果我在我的新AccountController上调用任何操作,我会得到这个:

  

Request.GetOwinContext()错误CS1061:&#39; HttpRequestMessage&#39;才不是   包含&#39; GetOwinContext&#39;的定义没有扩展方法   &#39; GetOwinContext&#39;接受第一个类型的参数   &#39; HttpRequestMessage&#39;可以找到(你是否错过了使用指令   或汇编参考?)

如果我在app.UseWebApi(httpConfig)声明中发表评论AccountController有效,那么我的其他控制人员就无法工作。在这里我得到这样的错误:

  

{       &#34; message&#34;:&#34;发生了错误。&#34;,       &#34; exceptionMessage&#34;:&#34;尝试创建类型为&#39; TestController&#39;的控制器时发生错误。确保控制器有   无参数的公共构造函数。&#34;,       &#34; exceptionType&#34;:&#34; System.InvalidOperationException&#34;,       &#34; stackTrace&#34;:&#34;在System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage)   请求,HttpControllerDescriptor controllerDescriptor,Type   controllerType)\ r \ n at   System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage   请求)\ r \ n at   System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()&#34 ;,       &#34; innerException&#34;:{           &#34; message&#34;:&#34;发生了错误。&#34;,           &#34; exceptionMessage&#34;:&#34;输入&#39; MyProject.Api.TestController&#39;没有默认构造函数&#34;,           &#34; exceptionType&#34;:&#34; System.ArgumentException&#34;,           &#34; stackTrace&#34;:&#34;在System.Linq.Expressions.Expression.New(Type type)\ r \ n at   System.Web.Http.Internal.TypeActivator.Create [TBASE](类型   instanceType)\ r \ n at   System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage   请求,输入controllerType,Func`1&amp;激活者)\ r \ n at   System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage   请求,HttpControllerDescriptor controllerDescriptor,Type   controllerType)&#34;       }}

知道这里发生了什么吗?

1 个答案:

答案 0 :(得分:1)

问题是您在启动期间没有使用相同的HttpConfiguration实例来配置使用OWIN的WebApi。

这样,您的OWIN Web API中间件不了解UnityContainer,并将使用其默认实现。因此,控制器的创建失败了。

对于Web Api配置和HttpConfiguration注册,请使用相同的UnityContainer

public class Startup {
    public void Configuration(IAppBuilder app) { 
        ConfigureOAuthTokenGeneration(app);

        ConfigureWebApi(app);

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

    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);
    }

    private void ConfigureWebApi(IAppBuilder app) {
        // configure Web Api
        GlobalConfiguration.Configure(WebApiConfig.Register);
        // Manually assign httpConfig from GlobalConfiguration
        HttpConfiguration httpConfig = GlobalConfiguration.Configuration;
        // Use same config with OWIN app
        app.UseWebApi(httpConfig);
    }
}

您正在多个位置配置web api。 WebApiConfig.Register方法应合并您要为HttpConfiguration配置的所有内容:

public static void Register(HttpConfiguration config) {
    var container = new UnityContainer();
    // Web API configuration and services

    string appStorageProvider = ConfigurationManager.AppSettings["StorageProvider"];
    var provider =(TestComposition.StorageProvider) Enum.Parse(typeof (TestComposition.StorageProvider), appStorageProvider, true);

    TestComposition.Setup(container, provider);
    container.RegisterType<GeneralLogger, GeneralLogger>();

    container.RegisterType<IExceptionLogger, ExceptionLogger>();

    config.EnableCors();

    config.DependencyResolver = new UnityResolver(container);
    config.Services.Add(typeof (IExceptionLogger), container.Resolve<GeneralLogger>());

    // Web API routes
    config.MapHttpAttributeRoutes();

    // configure formatter
    var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
    jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}