9

How can I get the url from web api in my view?

Example (from the msdn-blog):

[RoutePrefix("reviews")]
public class ReviewsController : ApiController
{
    // eg.: /reviews
    [Route]
    public IHttpActionResult Get() { ... }
    // eg.: /reviews/5
    [Route("{reviewId}")]
    public IHttpActionResult Show(int reviewId) { ... }
    // eg.: /reviews/5/edit
    [Route("{reviewId}/edit")]
    public IHttpActionResult Edit(int reviewId) { ... }
}

Now I want to construct "/reviews/edit" in my view, how can I do this?

I've tried creating a little extension method, but it requires me to give every route an actual "RouteName". Is there a method I can use (like in MVC) where I can just pass the controller and action?

@Url.Action("Edit", "Reviews)

The method I'm using now (with RouteName) also doesn't allow me to use integers as parameters (unless I pass a default value). If I do need to name all my routes, how can I create a route url, but pass my parameters in the "data"-portion of my request?

Current method:

public static string ResolveWebApiRoute(this UrlHelper urlHelper, string routeName, object routeValues = null)
{
    var newRouteValues = new RouteValueDictionary(routeValues);
    newRouteValues.Add("httproute", true);

    return urlHelper.RouteUrl(routeName, newRouteValues);
}

EDIT

When I used methods like Url.RouteUrl(new { controller = ..., action = ...}), It redirects directly to that action (e.g. new { controller = "Reviews", action = "Show"} --> /reviews/show, whilest I want it to redirect to /reviews/...

Barney
  • 2,355
  • 3
  • 22
  • 37
Team-JoKi
  • 1,766
  • 3
  • 15
  • 23
  • Looks like there is some confusion...you are trying to generate a link to a MVC action and NOT Web API. `httproute` is used for generating links to a Web API controller and not MVC as in your case. – Kiran Jan 17 '14 at 16:15
  • That was a wrong copy/paste, it's definitely a Web API controller, not an MVC controller, thanks for pointing that out – Team-JoKi Jan 20 '14 at 07:19

3 Answers3

21

Generating links to Web API routes always require a RouteName, so you should have something like below:

[Route("{reviewId}/edit", Name="EditView")]
public IHttpActionResult Edit(int reviewId) { ... }

You can then generate a link like /reviews/1/editto Web API.

Url.RouteUrl(routeName: "EditView", routeValues: new { httpRoute = true, reviewId = 1 });

or

Url.HttpRouteUrl(routeName: "EditView", routeValues: , reviewId = 1)

Note that route names need to be specified explicitly and they are no longer generated automatically like what @Karhgath is suggesting. This was a change made from RC to RTM version.

Kiran
  • 56,921
  • 15
  • 176
  • 161
  • 3
    so what would I need to do if I don't know that Id yet (I want to use it as a parameter in javascript)? – Team-JoKi Jan 21 '14 at 08:27
  • @Kiran, are you sure this is the only way? .. If yes, how can I avoid duplicate route names? – ebram khalil May 13 '16 at 12:32
  • 1
    @ebramkhalil Keep your route names in a static class like `RouteNameConstants` or something. It still won't ensure no duplicates, but at least all the magic strings will be in one place, and you won't be copy/pasting strings around as well. – crush Jul 30 '18 at 16:20
4

When using route attributes I was able to get the route of a WebApi2 controller from an MVC view using something like this:

Url.HttpRouteUrl("RouteName", new { })
voam
  • 1,006
  • 13
  • 24
0

In WebApi2 when using AttributeRouting, route names are named by default Controller.Action, but you could specify a RouteName also:

[RoutePrefix("reviews")]
public class ReviewsController : Controller
{
    // The route name is defaulted to "Reviews.Index" 
    [Route]
    public ActionResult Index() { ... }

    // The route name is "ShowReviewById"
    [Route("{reviewId}"), RouteName("ShowReviewById")]
    public ActionResult Show(int reviewId) { ... }

    // The route name is by default "Reviews.Edit"
    [Route("{reviewId}/edit")]
    public ActionResult Edit(int reviewId) { ... }

Then to call it in the view you only need to set the route name and send the parameters as an anonymous object:

// Outputs: /reviews/123
@Url.Action("ShowReviewById", new { reviewId = 123 })
// Outputs: /reviews/123/edit
@Url.Action("Reviews.Edit", new { reviewId = 123 })
Karhgath
  • 1,809
  • 15
  • 11
  • Well, I thought it was clear from the above, but I updated the answer to include the edit route example. If that's not clear, I'd like to have more info from you. – Karhgath Jan 17 '14 at 13:34
  • Yeah, I messed up with the example (I thought it was an API controller, but I copied an MVC example). My question remains though, how can I get the Url in web API? – Team-JoKi Jan 20 '14 at 07:23
  • Doesn't @Url.Action("Reviews.Edit", new { reviewId = 123 }) work?? (should give a url pointing to "/reviews/123/edit") When using Attribute Routing, route names are generated by default with a name like "Controller.Action", so "Reviews.Edit" should work fine no? I suspect I'm not understanding the real problem you have. – Karhgath Jan 20 '14 at 15:13
  • @Karhgath the `@Url.Action("Reviews.Edit", new { reviewId = 123 })` with anonymous attribute doesn't work. – Bodil Nov 26 '15 at 04:02