【发布时间】:2016-10-14 11:44:34
【问题描述】:
我们遇到了一个由另一个 ASP.NET Web 应用托管的 WebAPI 应用程序的奇怪问题。 WebAPI 控制器都使用 Ninject 进行映射,但 ASP.NET 主机站点不使用 Ninject。
问题是对任何 WebAPI 控制器的任何请求都会失败,并出现 Ninject 错误和 HTTP 500:
"An error occurred when trying to create a controller of type 'MyObjectsController'. Make sure that the controller has a parameterless public constructor."
但是,一旦对主 web 应用发出了一个请求(例如打开登录页面),WebAPI 调用就会按预期工作。 WebAPI 作为Application_Start 全局事件的一部分进行注册和初始化。无论第一个请求是在 WebAPI 下还是在 webapp 下都会触发启动事件,因此在主应用程序之前通过 WebAPI 时,它不会绕过全局启动。 WebAPI 注册是非常标准的东西:
GlobalConfiguration.Configure(AddressOf WebApiConfig.Register)
而且Register函数本身也没什么异常:
// Web API configuration and services
var cors = new EnableCorsAttribute("*", "*", "*", "X-Pagination");
//To allow cross-origin credentials in Web API
cors.SupportsCredentials = true;
config.EnableCors(cors);
// To disable host-level authentication inside the Web API pipeline and "un-authenticates" the request.
config.SuppressHostPrincipal();
config.Filters.Add(new HostAuthenticationFilter(Startup.OAuthBearerOptions.AuthenticationType));
// Web API routes
var constraintResolver = new DefaultInlineConstraintResolver();
constraintResolver.ConstraintMap.Add("nonzero", typeof(NonZeroConstraint));
//constraintResolver.ConstraintMap.Add("NonEmptyFolderIds", typeof(NonEmptyFolderIdsConstraint));
config.MapHttpAttributeRoutes(constraintResolver);
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
NinjectConfig 也很标准:
public static class NinjectConfig
{
/// <summary>
/// THe kernel of Ninject
/// </summary>
public static Lazy<IKernel> CreateKernel = new Lazy<IKernel>(() =>
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
RegisterServices(kernel);
return kernel;
});
private static void RegisterServices(KernelBase kernel)
{
kernel.Bind<IMyObjectRepository>().To<MyObjectRepository>().InRequestScope();
...
}
}
DI 用法的一个例子(同样,非常基本和标准)是:
public class MyObjectRepository : IMyObjectRepository
{
private readonly IMyOtherObjectRepository _objectRepository;
...
public MyObjectRepository(IMyOtherObjectRepository objectRepository)
{
_objectRepository = objectRepository;
...
}
...
}
我们希望在 WebAPI 可用于请求之前避免对 webapp 的初始请求的要求,但似乎没有什么可以让我们找到解决方案。
我们最初通过在 AppPool 配置中将 Start Mode 设置为 AlwaysRunning 并将 Start automatically 设置为 True 来尝试 IIS 预加载/应用程序初始化。我们还将preloadEnabled 启用到true,然后将applicationInitialization 配置部分添加到web.config,如下所示:
<system.webServer>
...
<applicationInitialization>
<add initializationPage="login.aspx" />
</applicationInitialization>
...
</system.webServer>
但是,这些更改和变体均未对 WebAPI 的行为产生任何影响。我们在网上搜索了更多帮助,但有点不知所措,因为我们遇到的几乎所有事情都指向设置 Start Mode、Start Automatically、preloadEnabled 和 applicationInitialization,然后它会神奇地工作,但这绝对不是我们的经验。
有人有建议或想法吗?
【问题讨论】:
标签: asp.net asp.net-web-api ninject