Search code examples
c#asp.netodataunity-containerowin

ASP.NET WebApi not working. All routes return 404


I have an asp.net web api with Unity as my dependency resolver and OWIN for OAuth authentication.

I create a Startup.cs using the Visual Studio "Add New Item"-menu, choosing OWIN Startup class:

[assembly: OwinStartup(typeof(MyNameSpace.Startup))]
namespace MyNameSpace
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            var config = new HttpConfiguration();
            WebApiConfig.Register(config);
            config.DependencyResolver = new UnityHierarchicalDependencyResolver(UnityConfig.GetConfiguredContainer());
            app.UseWebApi(config);
        }
    }
}

My WebApiConfig.cs looks like this:

public static void Register(HttpConfiguration config)
{
    // Web API configuration and services
    config.SuppressDefaultHostAuthentication();
    config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

    // Web API routes
    config.MapHttpAttributeRoutes();

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

Now, when I start the application I get a Forbidden response for the default url which is http://localhost:port/. The web api is hosted at http://localhost:port/api/. When I make a request for this url or any controller in the application it responds with Not Found.

Additionally, when I put a breakpoint in the Configuration method of the Startup class; once I start up the application it displays the following (I don't know if it is relevant):

message

I can't figure out what's wrong. It worked last night and I'm the only one who has been working on this project. The only thing I've done is add OData references from NuGet, but I removed those again once I established that the api was not working.

EDIT:

I should add that any breakpoint I set in the application currently displays the same message when I hover over it, so maybe it is relevant after all.

EDIT 2:

This is an excerpt from EmployeeController.cs:

[Authorize]
public class EmployeeController : ApiController
{
    private readonly IEmployeeService _service;

    public EmployeeController(IEmployeeService employeeService)
    {
        _service = employeeService;
    }

    [HttpGet]
    [ResponseType(typeof(Employee))]
    public IHttpActionResult GetEmployee(string employeeId)
    {
        var result = _service.GetEmployees().FirstOrDefault(x => x.Id.Equals(employeeId));
        if (result != null)
        {
            return Ok(result);
        }
        return NotFound();
    }

    [HttpGet]
    [ResponseType(typeof (IQueryable<Employee>))]
    public IHttpActionResult GetEmployees()
    {
        return Ok(_service.GetEmployees());
    }
...

EDIT 3

After restarting Visual Studio as suggested I can confirm that the breakpoint warning persists and shows up accross the entire application:

breakpoint in controller

EDIT 4

Removing OWIN references and Startup.cs, the application now springs back into life. I am able to place breakpoints again and make api calls. What's going on?


Solution

  • WebAPI Action Methods are based on HTTP Verb.

    If you want to name action method other than HTTP Verb, you want to look at Attribute Routing.

    In your example, you are using simple HTTP Verb. If so, you just need Get.

    public class EmployeeController : ApiController
    {
        // GET api/employee
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }
    
        // GET api/employee/5
        public string Get(int id)
        {
            return "value";
        }
    }