4

Here is the code that I am using to set the api url:

var clientUrl = '@Url.RouteUrl("ApiControllerAction", new { httproute="", controller = "Client"})';

In my route.config the route looks like this:

routes.MapHttpRoute(
            name: "ApiControllerAction",
            routeTemplate: "api/{controller}/{action}/{id}"
        );

And the action on my controller that I am trying to hit is this:

[ActionName("clients")]
    public IQueryable<Client> GetClients(int id)
    {
        return Uow.Clients.GetClients(id);
    }

I have a function in javascript that is trying to hit this api, but I am getting a 404:

var getClients = function (id) {
            return $.ajax(clientUrl + "/clients/" + id)
        };

When I call getClients(1) the url is trying to hit is this:

localhost:12345/clients/1

Rather than my expected url of this:

localhost:12345/api/client/clients/1

Any idea where this is going wrong? I had this working in another project and can't remember if there is something else I am supposed to do. If I inspect the javascript the clientUrl = ''.

ledgeJumper
  • 3,560
  • 14
  • 45
  • 92

2 Answers2

14

I came across this answer How to create ASP.NET Web API Url? which helped.

Example code for my answer here on GitHub

You can alter your @Url.RouteUrl code to include both the action name and the "ID" which currently appears not to be optional for your action route... this is probably why it is failing to find a match and returning an empty string. So try:

var clientUrl = '@Url.RouteUrl("ApiControllerAction", new { httproute="", controller = "Client", action = "clients" id=@... })';

NB. id=@... })'; at the end ... being what ever the id is going to be var or property on a model etc...

Or

You could of course just make ID optional which will also work:

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

Or

You may find it cleaner to avoid using an action... clients could live in its own controller ClientsController and you can use the routes and defaults to route to it:

routes.MapHttpRoute(
        name: "ApiControllerAction",
        routeTemplate: "api/client/clients/{id}",
        defaults: new { controller="Clients" }
    );

Then this should give you the required response:

var clientUrl = '@Url.RouteUrl("ApiControllerAction", new { httproute="", controller = "Clients" })';

//api/client/clients/

and...

var clientUrl = '@Url.RouteUrl("ApiControllerAction", new { httproute="", controller = "Clients", id=@... })';

//api/client/clients/x
Community
  • 1
  • 1
Mark Jones
  • 12,156
  • 2
  • 50
  • 62
0

Try to set the clientUrl like this:

var clientUrl = '@Url.RouteUrl("ApiControllerAction", new { httproute="", controller = "Client", action = "clients"})';

And then in change getClients to this:

var getClients = function (id) {
    return $.ajax(clientUrl + "/" + id)
};
MartinHN
  • 19,542
  • 19
  • 89
  • 131
  • I am not even hitting the controller in this code though. Well not yet. My issue is will getting that route into a variable in javascript that I can use. – ledgeJumper Oct 05 '12 at 04:53
  • Don't you need the action specified in the call to `Url.RouteUrl`? – MartinHN Oct 05 '12 at 04:55
  • I do that in my getClients js functions. I have a few different api controllers in my project, so I am trying to put each in a variable that I can then get to the different actions within. So I am trying to get www.domain.com/api/client from my Url.RouteUrl, but it is not find it for some reason. – ledgeJumper Oct 05 '12 at 04:59
  • even putting in the action does not do it for some reason. I feel like the razor line is not being called corrected because it is giving me back an empty string. Ideally i would like this to work without an explicit action call however. Any thoughts? – ledgeJumper Oct 05 '12 at 15:55