路由前缀 vs 路由

39

我理解 RoutePrefix 本身不会向路由表添加路由。您需要在操作中声明 Route 属性。我很难找到一个权威的博客或 MSDN 页面或其他一些东西,说明为什么默认情况下 RoutePrefix 不会向路由表添加路由。

是否有人有权威的帖子证明这种情况,并且如果有,能否告诉我是谁。非常感谢。

编辑 为了澄清我的问题

无法正常工作

[RoutePrefix("api/Steve")]
public class SteveController : ApiController
{
    public int get(){return 1000000;}
}

作品

[RoutePrefix("api/Steve")]
public class SteveController : ApiController
{
    [Route("")]
    public int get(){return 1000000;}
}
上述情况可行是因为我们明确说明了SteveController上的get操作具有空路由。一旦我们这样做,该路由就会添加到RouteTable中。
第一个情况不起作用,因为仅使用RoutePrefix无法将任何内容添加到路由表中。 RoutePrefix本身不会生成路由。这似乎是常识,我想找到一个可靠的来源,比如官方的Microsoft文档,解释其中的原因。
3个回答

28

路由前缀在属性路由中与路由设计相关联。

它用于为整个控制器设置公共前缀。

如果您阅读了引入该功能的发布说明,则可能更好地理解此主题。

ASP.NET Web API 2

属性路由

感谢Tim McCall的贡献,ASP.NET Web API现在支持属性路由。 使用属性路由,您可以通过注释操作和控制器来指定Web API路由,如下所示:

[RoutePrefix("orders")] 
public class OrdersController : ApiController 
{ 
    [Route("{id}")] 
    public Order Get(int id) { } 
    [Route("{id}/approve")] 
    public Order Approve(int id) { } 
} 

属性路由使您能够更好地控制 Web API 中的 URI。例如,您可以使用单个 API 控制器轻松定义资源层次结构:

public class MoviesController : ApiController 
{ 
    [Route("movies")] 
    public IEnumerable<Movie> Get() { } 
    [Route("actors/{actorId}/movies")] 
    public IEnumerable<Movie> GetByActor(int actorId) { } 
    [Route("directors/{directorId}/movies")] 
    public IEnumerable<Movie> GetByDirector(int directorId) { } 
} 

ASP.NET Web API 2.1 新功能

ASP.NET Web API 2.2 新功能

有一篇关于该主题的真正好文章。

ASP.NET 5 深入解析:路由

尽管我对该主题不是专家,但是这里是我的理解。

使用属性路由时,框架会检查控制器操作上的路由属性以创建要添加到路由表的路由条目。只要使用属性路由,就会使用 [RouteAttribute]。没有此属性,则行动将默认返回基于约定的路由。 RoutePrefixAttribute 是一个可扩展性点,它允许您更多地控制如何定义您的路由/Url。发行说明说得很清楚。

除了我的理解和最后提供的链接外,其他所有内容均引用自 MS 文档。


1
这些文章非常好,对于理解基础知识非常有帮助,但它们并没有回答我的问题。 - gh9
1
但是 RoutePrefix 的定义基本上已经解释了为什么它只适用于路由。它用于存储控制器中路由之间的 公共 前缀。 - Nkosi
我的问题不是它为什么能工作。而是我想看到一些证明它的来源。据我所知和通过谷歌搜索,这只是每个人都知道的常识信息。 - gh9
2
我给你点赞了...但是想在2023年的ASP.NET Core中补充一下,他们取消了RoutePrefix,因为它是旧的WebAPI 2库(Microsoft.AspNet.WebApi.Core)的一部分。在ASP.NET Core 7中,他们将MVC和WebAPI合并为一个新的MVC主库,现在都有一个模型,接近相同,但只使用“[Route]”。例如:MVC控制器属性是可选的,现在看起来像这样:[Route("[controller]/[action]")](默认路由),而WebAPI属性是不可选的,看起来像这样:[ApiController][Route("api/[controller]")](WebAPI总是使用属性)。哈哈,还有其他人感到困惑吗? - Stokely

18

以下是来自 MSDN(重点在于 "我")的描述,作为权威来源。

RouteAttribute

用于放置在控制器或操作上,以直接通过路由公开它。当放置在控制器上时,它适用于没有任何 System.Web.Mvc.RouteAttribute 的操作。

RoutePrefixAttribute

使用路由前缀标注控制器,该前缀适用于控制器内的所有操作。

可以看到,对于 Route 的描述提到了公开操作(s) ,但是对于 RoutePrefix 没有这样的描述。


0

RoutePrefix 属性用于在控制器级别指定公共路由前缀。它可以消除每个控制器方法上的公共路由前缀。 Route 属性用于在控制器中的方法级别指定路由。控制器中的每个方法都有自己独特的路由。

让我们通过代码来理解

没有 RoutePrefix 属性的代码:您可以看到前缀 "api/students" 在控制器中的每个方法中都重复出现。

public class StudentsController : ApiController
{
    [Route("api/students/{id}")]
    public Student Get(int id) 

    [Route("api/students/{id}/courses")]
    public IEnumerable<string> GetStudentCourses(int id)
}

带有RoutePrefix属性的代码:通过在控制器级别使用它,您可以看到RoutePrefix消除了在方法级别使用前缀的需要。

[RoutePrefix("api/students")]
public class StudentsController : ApiController
{
    [Route("{id}")]
    public Student Get(int id) 

    [Route("{id}/courses")]
    public IEnumerable<string> GetStudentCourses(int id)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接