MVC API tests – manage unknown error raised by HttpServer

Scenario: integration tests against ASP.Net MVC API.
MVC version 5.2

Create a base class test to manage the repetitive API GET/POST calls like:

protected HttpResponseMessage Execute(HttpMethod method, string url, T data)
{
url = BASE_URL + url;

HttpRequestMessage request = new HttpRequestMessage(method, url);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

JsonMediaTypeFormatter formatter = new JsonMediaTypeFormatter();
formatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
if (method == HttpMethod.Post && data != null)
request.Content = new ObjectContent(data, formatter);

using (var server = new HttpServer(GetConfiguration()))
using (var client = new HttpClient(server))
{
var response = client.SendAsync(request).Result;
return response;
}
}

Boom.

500. Internal server Error.

The server is set like this:
private HttpConfiguration GetConfiguration()
{
HttpConfiguration configuration = new HttpConfiguration();
//var dependencyResolver = new WindsorDependencyResolver(container);
//configuration.DependencyResolver = dependencyResolver;
WebApiConfig.Register(configuration);

// remove all HostAuthenticationFilter due to the error “no OWIN Authentication manager…”
foreach (var filter in configuration.Filters.Where(f => f.Instance is HostAuthenticationFilter).ToList())
configuration.Filters.Remove(filter.Instance);

return configuration;
}

mmhh… try to debug:
It enter in the ApiController, get the data from the REpository and it exit from the class with a nice colelction of data… what is wrong ???

Routing is ok, it is actually passing the request to the right controller.
Injection of repositories is ok, it is fetching and returning data.
Log4Net is ok, I’m not calling the “log4net.Config.XmlConfigurator.Configure();” without a proper configuration in app.config.

Adding “configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;”
is absolutely useless for this problem.

What to do now?

I’ll check one of 2 or 3 previous project where I’ve already done this a where I spent 1,2 or 7 days to figure out this ALL THE TIMES fucking problem !

Microsoft ASP MVC 5

In MVC 5 Microsoft introduced the Attribute Routing functionality.
With it defining the Route for an Action become immediate and there is the advantage to be more safe when you change a routing, you cannot break previous routing rules.
To enable it you have to call the MapMvcAttributeRoutes() method on the RouteCollection.
GlobalConfiguration.Configuration.MapHttpAttributeRoutes();

Constraints on parameter type become more simple to define.
You can define optional parameters and default values more simply too.

Another feature I use all the time is the RoutePrefix: you can define the “controller” segment on the router only on the Controller definition, making more simple and readable changing the routes on the Actions.

You can continue to restrict the HTTP verbs allowed for an Action using [HttpGet], [HttpPost] and [AcceptVerbs]. This permits to have the same URL route for different Actions; for example you can request for the existence of a file (using HEAD) and to downlod the file (using GET) using the same URL.

[Route("Ping"), AcceptVerbs("Head", "Get")] 
public ActionResult Ping() {     return Content("pong (" + Request.HttpMethod + ")"); 
}

Sources:

  1.  https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5