【问题标题】:Construct url in view for Web Api with attribute routing使用属性路由为 Web Api 构建视图中的 url
【发布时间】:2014-02-06 19:17:02
【问题描述】:

如何在我的视图中从 web api 获取 url?

示例(来自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) { ... }
}

现在我想在我的视图中构造“/reviews/edit”,我该怎么做?

我尝试过创建一个小扩展方法,但它要求我为每条路由指定一个实际的“RouteName”。有没有我可以使用的方法(比如在 MVC 中),我可以只传递控制器和操作?

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

我现在使用的方法(使用 RouteName)也不允许我使用整数作为参数(除非我传递默认值)。如果我确实需要命名所有路由,如何创建路由 url,但在请求的“数据”部分传递我的参数?

当前方法:

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);
}

编辑

当我使用Url.RouteUrl(new { controller = ..., action = ...}) 之类的方法时,它会直接重定向到该操作(例如new { controller = "Reviews", action = "Show"} --> /reviews/show,而我希望它重定向到/reviews/...

【问题讨论】:

  • 看起来有些混乱...您正在尝试生成指向 MVC 操作而不是 Web API 的链接。 httproute 用于生成指向 Web API 控制器的链接,而不是像您的情况那样的 MVC。
  • 这是一个错误的复制/粘贴,它绝对是一个 Web API 控制器,而不是一个 MVC 控制器,感谢您指出这一点

标签: c# asp.net-mvc asp.net-web-api attributerouting


【解决方案1】:

在 WebApi2 中使用AttributeRouting 时,路由名称默认命名为Controller.Action,但您也可以指定RouteName

[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) { ... }

然后在视图中调用它只需要设置路由名称并将参数作为匿名对象发送:

// Outputs: /reviews/123
@Url.Action("ShowReviewById", new { reviewId = 123 })
// Outputs: /reviews/123/edit
@Url.Action("Reviews.Edit", new { reviewId = 123 })

【讨论】:

  • 好吧,我认为从上面很清楚,但我更新了答案以包含编辑路线示例。如果不清楚,我希望您能提供更多信息。
  • 是的,我把这个例子搞砸了(我以为它是一个 API 控制器,但我复制了一个 MVC 例子)。我的问题仍然存在,我怎样才能在 Web API 中获取 URL?
  • @Url.Action("Reviews.Edit", new { reviewId = 123 }) 不起作用吗? (应该给出一个指向“/reviews/123/edit”的url)当使用属性路由时,默认情况下会生成路由名称,名称类似于“Controller.Action”,所以“Reviews.Edit”应该可以正常工作不是吗?我怀疑我不了解您遇到的真正问题。
  • @Karhgath 具有匿名属性的@Url.Action("Reviews.Edit", new { reviewId = 123 }) 不起作用。
【解决方案2】:

生成指向 Web API 路由的链接始终需要 RouteName,因此您应该有如下内容:

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

然后您可以生成类似/reviews/1/editto Web API 的链接。

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

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

请注意,需要明确指定路线名称,并且它们不再像 @Karhgath 所建议的那样自动生成。这是从 RC 版本到 RTM 版本的更改。

【讨论】:

  • 那么如果我还不知道那个 Id 我需要做什么(我想将它用作 javascript 中的参数)?
  • @Kiran,你确定这是唯一的方法吗? .. 如果是,我怎样才能避免重复的路线名称?
  • @ebramkhalil 将您的路线名称保存在静态类中,例如 RouteNameConstants 或其他东西。它仍然不能确保没有重复,但至少所有魔术字符串都将在一个地方,并且您也不会复制/粘贴字符串。
【解决方案3】:

当使用路由属性时,我可以使用以下方式从 MVC 视图中获取 WebApi2 控制器的路由:

Url.HttpRouteUrl("RouteName", new { })

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-24
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 2014-12-22
    相关资源
    最近更新 更多