locked
Auto-start ASP.NET application hosting WebAPI instance RRS feed

  • Question

  • User1112784522 posted

    We're having an odd issue with a WebAPI application hosted by another ASP.NET webapp. The WebAPI controllers are all mapped with Ninject but the ASP.NET host site does not use Ninject.

    The issue is that after server restarts, any requests to any of the WebAPI controllers fail with a Ninject error and HTTP 500:

    "An error occurred when trying to create a controller of type 'MyObjectsController'. Make sure that the controller has a parameterless public constructor."

    However, once even a single request to the main webapp is made (such as opening the login page) then the WebAPI calls all work as expected. The WebAPI is registered and initialized as part of the

    Application_Start

    global event. The start event is triggered regardless of whether the first request comes in under the WebAPI or the webapp so it's not bypassing the global startup when coming through the WebAPI before the main app. The WebAPI registration is pretty standard stuff:

    GlobalConfiguration.Configure(AddressOf WebApiConfig.Register)

    And the Register function itself is nothing unusual:

    // 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();

    The NinjectConfig is also pretty standard:

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

    An example of the DI usage (again, very basic and standard) is:

    public class MyObjectRepository : IMyObjectRepository
    {
        private readonly IMyOtherObjectRepository _objectRepository;
        ...
    
        public MyObjectRepository(IMyOtherObjectRepository objectRepository)
        {
            _objectRepository = objectRepository;
            ...  
        }
        ...
    }

    We want to avoid the requirement of the initial request to the webapp before the WebAPI is available for requests but nothing seems to be getting us towards a solution.

    We initially tried out the IIS preloading/app initialization by setting "Start Mode" to "AlwaysRunning" and "Start automatically" to "True" in the AppPool config. We also enabled "preloadEnabled" set to "true" and then added the "applicationInitialization" config section to the web.config such as the following:

    <system.webServer>
      ...
      <applicationInitialization>
        <add initializationPage="login.aspx" />
      </applicationInitialization>
      ...
    </system.webServer>

    However, none of these changes and variations of made any difference to the behavior of the WebAPI. We've scoured the web for more help but are at somewhat of a loss as pretty much everything we've come across points to setting the "Start Mode", "Start Automatically", "preloadEnabled", and "applicationInitialization" and then it will magically work but that's definitely not our experience.

    Does anyone have suggestions or ideas?

    Thursday, July 7, 2016 2:10 PM

All replies

  • User36583972 posted

    Hi kettch19,

    From your error message, you can refer the following post solutions. It may be helpful for you.

    WebApi 2 and Ninject - Not Resolving:

    http://stackoverflow.com/questions/21113274/webapi-2-and-ninject-not-resolving

    However, none of these changes and variations of made any difference to the behavior of the WebAPI. We've scoured the web for more help but are at somewhat of a loss as pretty much everything we've come across points to setting the "Start Mode", "Start Automatically", "preloadEnabled", and "applicationInitialization" and then it will magically work but that's definitely not our experience.

    You can visit the IIS forum for getting better support.

    http://forums.iis.net/

    Best Regards,

    Yohann Lu

    Friday, July 8, 2016 4:48 AM