404 not found when self hosting ASP.NET Web API, works fine within IIS
<p>I'm currently stuck with a self-hosted Web API I'm trying to use within a unit test.</p>

<p>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.</p>

<p>Here's the <strong>fully working config</strong> I used for my Web API when hosted within IIS:</p>

<pre><code>public class WebApiApplication : System.Web.HttpApplication
{
    /// &lt;summary&gt;
    /// Entry point of the application.
    /// &lt;/summary&gt;
    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 =&gt; i is ActionDescriptorFilterProvider);
    config.Services.Remove(typeof(IFilterProvider), defaultprovider);
    config.Services.Add(typeof(IFilterProvider), new UnityFilterProvider(container));
}
</code></pre>

<hr>

<p>Here's the <strong>non-working config</strong> I'm using for my unit test:</p>

<pre><code>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 =&gt; 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
</code></pre>

<p>I also tried the new Owin hosting services, same result:</p>

<pre><code>public class Startup
{
    private static IUnityContainer container;

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

    /// &lt;summary&gt;
    /// This code configures Web API. The Startup class is specified as a type
    /// parameter in the WebApp.Start method.
    /// &lt;/summary&gt;
    /// &lt;param name="appBuilder"&gt;The application builder.&lt;/param&gt;
    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 =&gt; 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);
    }
}
</code></pre>

<p>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.</p>

<p>Any hint?</p>