Search code examples
url-routingasp.net-web-api

Why doesn't this Web Api route work?


I declared these routes and controllers:

public class RouteConfig
{
    public static readonly string MVC_ROUTING = "Default";
    public static readonly string WEB_API_ROUTING = "Api";

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapRoute(
          name: MVC_ROUTING,
          url: "{controller}/{action}/{id}",
          defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
          constraints: new { id = @"^[0-9]*$" }
      );

      routes.MapRoute(
          name: WEB_API_ROUTING,
          url: "api/{controller}/{action}/{id}",
          defaults: new {id = UrlParameter.Optional },
          constraints: new { id = @"^[0-9]*$" }
      );
    }
}

public class QuoteController : ApiController
{
    private readonly QuoteService quoteService;
    public QuoteController()
    {
        quoteService = new QuoteService();
    }

    // GET api/<controller>
    public IEnumerable<QuoteModel> Get()
    {
        return quoteService.GetAllQuotes().Map<QuoteModel>();
    }

    // GET api/<controller>/5
    public QuoteModel Get(int id)
    {
        return quoteService.GetQuoteById(id).Map<QuoteModel>();
    }

    // POST api/<controller>
    public HttpResponseMessage Post(QuoteModel quoteModel)
    {
        Quote quote = quoteModel.Map<Quote>();
        quoteService.AddNewQuote(quote);

        string uri = Url.Link(RouteConfig.WEB_API_ROUTING, new { id = quote.QuoteId,controller="Quote",action="Get"});
        return Request.CreateResponse(HttpStatusCode.OK, uri);
    }

    // PUT api/<controller>/5
    public void Put(QuoteModel quote)
    {
        quoteService.Update(quote.Map<Quote>());
    }

    // DELETE api/<controller>/5
    public void Delete(int id)
    {
        quoteService.DeleteQuote(id);
    }
}

I don't understand why these routes work:

But this one doesn't:


Solution

  • Part of the problem is that you have registered your Api routes in the RouteConfig rather than the WebApiConfig. Remove the Web Api route from the RouteConfig and then open up the WebApiConfig.

    You probably have a default route in the WebApiConfig already; Change the routes in there as follows:

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "Api",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional },
                constraints: new { id = @"\d*", action = @"[a-zA-Z]+" }
            );
    
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional },
                constraints: new { id = @"\d*" }
            );
        }
    }
    

    You should now be able to hit all the routes listed above. A better alternative is to use Attribute Routing which you can read about here.