简体   繁体   中英

404 not found when self hosting ASP.NET Web API, works fine within IIS

I'm currently stuck with a self-hosted Web API I'm trying to use within a unit test.

Whatever route I try, I get a 404 not found error. The issue is, when hosting the very same Web API within IIS, everything works fine. I'm guessing it's a simple typo/mistake in my test config, but I can't make it work, any help appreciated.

Here's the fully working config I used for my Web API when hosted within IIS:

public class WebApiApplication : System.Web.HttpApplication
{
    /// <summary>
    /// Entry point of the application.
    /// </summary>
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    }
}

public static void Register(HttpConfiguration config)
{
    // IoC configuration
    var container = new UnityContainer();
    UnityContainerConfigurator.Configure(container, new PerRequestLifetimeManager());

    // Set the dep resolver
    config.DependencyResolver = new UnityDependencyResolver(container);

    // Web API routes
    config.MapHttpAttributeRoutes();

    // Only supports JSON formatter
    config.Formatters.Clear();
    config.Formatters.Add(new JsonMediaTypeFormatter());
    config.Formatters.JsonFormatter.SerializerSettings = CustomJsonSerializerSettings.Create();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional });

    // Custom filter
    var providers = config.Services.GetFilterProviders().ToList();
    var defaultprovider = providers.Single(i => i is ActionDescriptorFilterProvider);
    config.Services.Remove(typeof(IFilterProvider), defaultprovider);
    config.Services.Add(typeof(IFilterProvider), new UnityFilterProvider(container));
}

Here's the non-working config I'm using for my unit test:

var config = new HttpSelfHostConfiguration(webApiURL);

#if DEBUG
    // For debug purposes
    config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
#endif

// Web API routes
config.MapHttpAttributeRoutes();

// Only supports JSON formatter
config.Formatters.Clear();
config.Formatters.Add(new JsonMediaTypeFormatter());
config.Formatters.JsonFormatter.SerializerSettings = CustomJsonSerializerSettings.Create();

config.Routes.MapHttpRoute(
      name: "DefaultApi",
      routeTemplate: "api/{controller}/{action}/{id}",
      defaults: new { id = RouteParameter.Optional });

// Custom filter
var providers = config.Services.GetFilterProviders().ToList();
var defaultprovider = providers.Single(i => i is ActionDescriptorFilterProvider);
config.Services.Remove(typeof(System.Web.Http.Filters.IFilterProvider), defaultprovider);
config.Services.Add(typeof(System.Web.Http.Filters.IFilterProvider), new UnityFilterProvider(this.UnityContainer));

// Overwrites the IoC configuration
config.DependencyResolver = new UnityDependencyResolver(this.UnityContainer);

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

this.webApiServer = new HttpSelfHostServer(config);
this.webApiServer.OpenAsync().Wait();
enter code here

I also tried the new Owin hosting services, same result:

public class Startup
{
    private static IUnityContainer container;

    /// <summary>
    /// Overwrites the IoC configuration.
    /// </summary>
    /// <param name="container">The container.</param>
    public static void ConfigureIoC(IUnityContainer container)
    {
        Startup.container = container;
    }

    /// <summary>
    /// This code configures Web API. The Startup class is specified as a type
    /// parameter in the WebApp.Start method.
    /// </summary>
    /// <param name="appBuilder">The application builder.</param>
    public void Configuration(IAppBuilder appBuilder)
    {
        if (Startup.container == null)
        {
            throw new Exception("Call ConfigureIoC first");
        }

        // Configure Web API for self-host.
        HttpConfiguration config = new HttpConfiguration();
        config.Routes.MapHttpRoute(
              name: "DefaultApi",
              routeTemplate: "api/{controller}/{action}/{id}",
              defaults: new { id = RouteParameter.Optional });

        // Web API routes
        config.MapHttpAttributeRoutes();

        // Only supports JSON formatter
        config.Formatters.Clear();
        config.Formatters.Add(new JsonMediaTypeFormatter());
        config.Formatters.JsonFormatter.SerializerSettings = CustomJsonSerializerSettings.Create();

        // Custom filter
        var providers = config.Services.GetFilterProviders().ToList();
        var defaultprovider = providers.Single(i => i is ActionDescriptorFilterProvider);
        config.Services.Remove(typeof(System.Web.Http.Filters.IFilterProvider), defaultprovider);
        config.Services.Add(typeof(System.Web.Http.Filters.IFilterProvider), new UnityFilterProvider(container));

        // Overwrites the IoC configuration
        config.DependencyResolver = new UnityDependencyResolver(Startup.container);

        appBuilder.UseWebApi(config);
    }
}

The very same REST request I'm starting with Postman is a success when hosted within IIS, and a 404 when hosted within my unit test as a self hosted service.

Any hint?

You should check whether your self hosting application contains a Virtual Directory (like IIS). And as you mentioned ensure the base path is valid.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM