【问题标题】:Auto-start ASP.NET application hosting WebAPI instance自动启动托管 WebAPI 实例的 ASP.NET 应用程序
【发布时间】: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


    【解决方案1】:

    安装Ninject integration for WebApi nuget 包。它创建一个在启动时初始化 Ninject 的文件。这是doc。

    【讨论】:

    • 我们早就安装了所有的 Ninject 和 WebAPI 依赖项,并且运行良好。正如我上面提到的,在向主 webapp 发出单个请求(例如进入登录屏幕)后,一切都可以完美运行。
    • @Kettch19 从您的示例代码中我不清楚NinjectConfig 是如何使用的,您也不清楚如何设置依赖注入
    • 我在原始帖子中明确添加了我们的NinjectConfig,所以除非您有特定要求,否则我不确定您还需要什么。我刚刚添加了一个我们的 DI 使用示例(简化),但它是非常标准的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-02
    • 1970-01-01
    • 2015-01-29
    • 1970-01-01
    • 2018-11-17
    相关资源
    最近更新 更多