18

I have a solution with two projects. One Web Api bootstap project and the other is a class library.

The class library contains a ApiController with attribute routing. I add a reference from web api project to the class library and expect this to just work.

The routing in the web api is configured:

config.MapHttpAttributeRoutes();

The controller is simple and looks like:

public class AlertApiController:ApiController
{
    [Route("alert")]
    [HttpGet]
    public HttpResponseMessage GetAlert()
    {
        return Request.CreateResponse<string>(HttpStatusCode.OK,  "alert");
    }
}

But I get a 404 when going to the url "/alert".

What am I missing here? Why can't I use this controller? The assembly is definitely loaded so I don't think http://www.strathweb.com/2012/06/using-controllers-from-an-external-assembly-in-asp-net-web-api/ is the answer here.

Any ideas?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
user1613512
  • 3,590
  • 8
  • 28
  • 32
  • 2
    Are you sure the assembly is loaded when the MapAttributeRoutes is called? Try calling into some dummy static method in that assembly right before doing the mapping. – Darrel Miller Mar 18 '14 at 11:21
  • Still not working, not by the default route nor attribute routing. – user1613512 Mar 19 '14 at 11:42
  • @user1613512: Did you ever manage to figure this out? I am having the same problem (have multiple assemblies - plugins, etc - and the [RoutePrefix] attribute is ignored.. I can only use the services via the default route config. – Matt Aug 31 '14 at 07:19

3 Answers3

16

Try this. Create a class in your class library project that looks like this,

public static class MyApiConfig {


  public static void Register(HttpConfiguration config) {
      config.MapHttpAttributeRoutes();
  }
}

And wherever you are currently calling the config.MapHttpAttributeRoutes(), instead call MyApiConfig.Register(config).

von v.
  • 16,868
  • 4
  • 60
  • 84
Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
  • 1
    It doesn't make much sense to me why this would help. Why does the context within which the same method on the same object instance is called affect the outcome of the method call? That seems to indicate you would be expected to have to do this on all of the class libraries you have which include `ApiController`'s. If this was just a trick to ensure he really had the class library loaded prior to mapping the routes, then my similar issue must be different. – DannyMeister Aug 23 '14 at 02:18
  • 4
    @DannyMeister Yes, this is just a technique to guarantee that the assembly containing the controllers has actually been loaded. – Darrel Miller Aug 23 '14 at 20:57
11

One possibility is you have 2 routes on different controllers with the same name.

I had 2 controllers both named "UploadController", each in a different namespace and each decorated with a different [RoutePrefix()]. When I tried to access either route I got a 404.

It started working when I changed the name of one of the controllers. It seems the Route Attribute is only keyed on the class name and ignores the namespace.

Mike4QL
  • 111
  • 1
  • 3
  • 1
    This helped me a bunch. I had features namespaced so controllers where just called namespace.Controller. WebAPI2 decideds to silently convert that into 404s, rather than give me any info about what is happening :S. – Beau Trepp Dec 17 '15 at 07:33
  • GREATE! Thank you so much! That was my case. – Cleiton Aug 04 '16 at 19:34
  • Had this issue as well. We ventured into attribute routing precisely to avoid creating separate controller classes for the same purpose, with different routes. And it did not work. Kept getting 404 errors until we changed the class names to different names. If we have to create different classes anyway, `MapHttpRoute` would be much simpler to implement. – Hari Oct 20 '17 at 17:19
  • Did any of you find a solution which did not require the controller to have diffferent name? I have tried some, and even tried moving into a separate assembly, but without luck. – TryingToImprove Nov 23 '18 at 11:45
1

We were trying to solve a similar problem. The routes within the external assembly were not registering correctly. We found one additional detail when trying the solution shown on this page. The call to the external assembly "MyApiConfig.Register" needed to come before the call to MapHttpRoute

HttpConfiguration config = new HttpConfiguration();
MyExternalNamespace.MyApiConfig.Register(config); //This needs to be before the call to "config.Routes.MapHttpRoute(..."
config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
DavB.cs
  • 579
  • 5
  • 6