0

I am trying to work through an example using HttpClient from the ASP.NET Web Api but I am receiving a status code 500 in the response and I don't know why.

I have the following code in a test:

        var baseAddress = new Uri("http://localhost:54997");
        var config = new HttpSelfHostConfiguration(baseAddress);
        var server = new HttpSelfHostServer(config);

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

        using (var client = new HttpClient(server))
        {

            client.BaseAddress = baseAddress;
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            var response = client.GetAsync("/api/user/getUserDetails").Result;               
        }

My controller method is like this:

    [HttpGet]
    [ActionName("getUserDetails")]
    public string GetUserDetails()
    {
        return "hello";
    }

The controller action responds fine in Fiddler.

The error seems to be thrown in the Content property of the response.

[System.Net.Http.ObjectContent<System.Web.Http.HttpError>] = {System.Net.Http.ObjectContent<System.Web.Http.HttpError>}

I'm sorry that's not much to go on.

EDIT Please see Darin's answer below. I also put the code in a console application and it works fine - so why not in the test project?

Can someone point me in the right direction of what might be wrong please?

Warren Sergent
  • 2,542
  • 4
  • 36
  • 42
davy
  • 4,474
  • 10
  • 48
  • 71
  • Turn on tracing and add a ConsoleListener and you should see where the problem appears. – Darrel Miller May 16 '13 at 13:27
  • After getting the response in the above code, can you do `response.Content.ReadAsStringAsync().Result` to see if you get more details about the error? Also if there are no error details, can you try setting the error detail policy to Always `config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always`(this shouldn't matter as its localhost, but you can give it a try) – Kiran May 16 '13 at 15:31
  • Take a look at my question and answer here: http://stackoverflow.com/q/23438416/1828879 Your BaseAddress and relative URIs have the wrong trailing and leading slashes. – Timothy Shields Jun 13 '14 at 18:28

3 Answers3

1

Weird, the following Console application works perfectly fine for me:

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http;
using System.Web.Http.SelfHost;

class Program
{
    static void Main(string[] args)
    {
        var baseAddress = new Uri("http://localhost:54997");
        var config = new HttpSelfHostConfiguration(baseAddress);
        var server = new HttpSelfHostServer(config);
        ((HttpConfiguration)config).Routes.MapHttpRoute(
            name: "default",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        using (var client = new HttpClient(server))
        {
            client.BaseAddress = baseAddress;
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            var response = client.GetAsync("/api/user/getUserDetails").Result;
            Console.WriteLine(response.Content.ReadAsStringAsync().Result);
        }
    }
}

public class UserController : ApiController
{
    [HttpGet]
    [ActionName("getUserDetails")]
    public string GetUserDetails()
    {
        return "hello";
    }
}

You might inspect the response text returned by the server to see if you could gather more information about the problem:

Console.WriteLine(response.Content.ReadAsStringAsync().Result);
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Thanks. I tried the same and it works so why not from the test project? – davy May 16 '13 at 13:54
  • 2
    Maybe you have something in this so called *test project* that is preventing it from working. Pretty hard to tell what without showing your code. I have showed you a fully working example. Now if you expect me guessing what you have in your test project as code, well, sorry, it ain't gonna happen. I don't have a magic crystal ball allowing me to read other people's minds/code. – Darin Dimitrov May 16 '13 at 19:33
1

This in-memory hosting thing is awesome. BUT.....

It seems that if the controller you're testing uses anything in your app config, it fails. For some reason, my in-memory server returns nulls for all; app config values in the web.config.

Does anyone know a way to have the HttpServer read those?

It works fine when hosted in IIS express....I only see the issue when I host in memory.

Help! :)

Eric Langland
  • 95
  • 2
  • 10
0

I'm not sure why the Self host server is failing in your test project, but you really don't need it anyway. Try the following using an in-memory host:

    var config = new HttpConfiguration();
    var server = new HttpServer(config);

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

    using (var client = new HttpClient(server))
    {

        client.BaseAddress = baseAddress;
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        var response = client.GetAsync("/api/user/getUserDetails").Result;               
    }
Darrel Miller
  • 139,164
  • 32
  • 194
  • 243