我有一个以前允许匿名访问的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; }}
知道这里发生了什么吗?
答案 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();
}