I have few integration tests that was working correctly with Web API 1, after I have upgraded to Web API 2 (5.0) they are not working and giving me the null reference when calling the following code:
string uri = Url.Link(HttpRouteConstants.RouteName, new { param1 =
paramValue1, param2 = paramValue2 });
Basically the Url.Link can't find the route (at least I think this is the problem). I think that problem is with the way HttpConfiguration & routes are being registered in the Web API 2. We had to change the WebApiConfig registration call
from
WebApiConfig.Register(config)
to
GlobalConfiguration.Configure(WebApiConfig.Register);
and now when using the integration test setup, where I'm providing the HttpServer with HttpConfiguration instance I can't call something like GlobalConfiguration.Configure(WebApiConfig.Register); but I'm using the old way and doing the following WebApiConfig.Register(config) which doesn't seems to work correctly. FYI my routing configs are placed in the WebApiConfig.
Does anyone know any workarounds ?
This is the stack I'm using:
- VS 2013 (.NET 4.5.1)
- WebAPI 2 (convention-based routing & attribute routing)
- xUnit
- Ninject
Update
Here is the integration test code sample
// Create configuration
HttpConfiguration config = new HttpConfiguration();
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
config.DependencyResolver = new NinjectDependencyResolver(Kernel);
//WebApiConfig.Register(config); Below is the excerpt from WebApiConfig
config.EnableCors((System.Web.Http.Cors.ICorsPolicyProvider)config.DependencyResolver.GetService(typeof(System.Web.Http.Cors.ICorsPolicyProvider)));
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: HttpRouteConstants.ApplicationAPIRouteName,
routeTemplate: CoreRouteConstants.DefaultApplicationControllerRoute + "/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: HttpRouteConstants.DefaultAPIRouteName,
routeTemplate: CoreRouteConstants.DefaultControllerRoute + "/{id}",
defaults: new { id = RouteParameter.Optional }
);
HttpServer server = null;
try
{
server = new HttpServer(config);
}
catch (Exception ex)
{
throw ex;
}
string controller = String.Format("{0}{1}/api/MyController/{2}/", HttpServerBaseAddress, param1, param2);
var client = new HttpClient(Server);
using (HttpResponseMessage response = client.DeleteAsync(controller, new CancellationTokenSource().Token).Result)
{
response.IsSuccessStatusCode.Should().BeFalse();
response.StatusCode.Should().Be(HttpStatusCode.NotFound);
}
//Below is the code from MyController
public virtual async Task<HttpResponseMessage> DeleteAsync([FromUri]object key)
{
HttpResponseMessage response = null;
HttpStatusCode statusCode = HttpStatusCode.OK;
bool result = await Store.DeleteAsync(key);
if (!result)
statusCode = HttpStatusCode.NotFound;
response = Request.CreateResponse<bool>(statusCode, result);
string uri = Url.Link(HttpRouteConstants.ApplicationAPIRouteName, new { param1 = "param1", id = key });
//NOTE: uri is null here as I mentioned
response.Headers.Location = new Uri(uri);
return response;
}
Thanks