Reputation: 48975
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?
Upvotes: 1
Views: 2174
Reputation: 58921
You should check whether your self hosting application contains a Virtual Directory (like IIS). And as you mentioned ensure the base path is valid.
Upvotes: 1