Jam*_*ery 26 asp.net asp.net-mvc-4
我对如何在Web应用程序中处理单数和复数路由和控制器感到困惑.
该网站是一个简单的报价网站 - 认为爱因斯坦,莎士比亚等不是保险.在项目中,我有一个名为`QuoteController'的控制器.控制器名称是单数,这是否意味着控制器应该只处理单引号的显示?IE
/quote/love-is-a-battlefield-1
Run Code Online (Sandbox Code Playgroud)
那么我是否需要另一个控制器来显示多个引号(复数)?例如:
/quotes/ (would default to most recent)
/quotes/new
/quotes/shakespeare
/quotes/popular
Run Code Online (Sandbox Code Playgroud)
为单数和复数路线设置单独的控制器是惯例还是良好实践?我希望这是有道理的.
Yor*_*rro 39
仅仅因为asp-mvc的默认控制器具有单数名称,并不意味着你应该为所有控制器实现单数形式.
正确答案是:它取决于控制器所代表的实体数量.
单数,例如,AccountController它是单数的,因为它表示仅与单个帐户有关的动作(动作方法).
Plural如果您的控制器包含至少一个在单个事务处理多个实体的操作方法.
示例复数格式
users/update/3
Run Code Online (Sandbox Code Playgroud)
上面的路线让你觉得你正在编辑所有用户,如果你像句子一样读它就没有意义.但是,如果您像查询一样阅读您的路线,那将更有意义.
如果我们考虑一下,路由是一个查询:{entities}/{action}/{parameter}看起来像是对我的查询.
users/users/all读取速记"选择所有用户表"
users/123读取"从用户表中选择单个实体"
users/update/123读取"从用户表更新单个实体"
主要网站使用复数格式,请参阅下面的示例
stackoverflow.com/questions <- list of questions (multiple)
stackoverflow.com/questions/18570158 <- individual question (single)
stackoverflow.com/questions/ask <- new question (single)
stackoverflow.com/users <- display list of users (multple)
stackoverflow.com/users/114403 <- individual user (single)
asp.net/mvc/tutorials <- display list of tutorials (multiple)
asp.net/mvc/tutorials/mvc-5 <- individual tutorial (single)
facebook.com/messages/ <- Display list of messages (multiple)
facebook.com/messages/new <- Create a single message (single)
facebook.com/messages/john <- view individual messages (multiple)
Run Code Online (Sandbox Code Playgroud)
我相信英语语法应该严格地纳入每个编程方面.它看起来更自然,并导致良好的代码卫生.
这是程序员StackExchange中提出的一个问题,建议将类名保持单数。我特别喜欢其中一个答案中的逻辑:“用于拧紧螺丝的工具称为“螺丝起子”,而不是“螺丝起子”。 我同意。名称应保留为名词和形容词。
就路由而言,最佳实践似乎倾向于将路由使用复数名词,并避免使用动词。Apigee的博客说:“避免使用混合模型,对于某些资源,您使用单数形式;对于其他资源,则使用复数形式。保持一致可使开发人员在学习使用API时预测和猜测方法调用。” 并建议根据热门网站的使用情况使用单数或复数形式。他们在路线中使用单数名词的唯一示例是Zappos网站,该网站以http://www.zappos.com/Product作为路线;但是,如果您检查站点,它并不是到产品资源的确切路径,而是一个查询,可能是针对所有产品的查询。您可以输入http://www.zappos.com/anything并获得结果页面。因此,我不会投入太多库存。
像其他博客这样一个从mwaysolutions(随机查找)说“使用的名词,但没有动词”和“使用复数名词”。除了其他观点,大多数博客/文章都倾向于说同样的话。复数名词,无动词。
TL; DR:对控制器使用单数名词,对路径使用复数名词。
控制器和路由代表两个不同的概念。控制器是一个类或一个蓝图。类似的压模,我不会说我有一个UnicornsStamper我会说我有一个UnicornStamper,使一个独角兽与我能与麒麟邮票收藏的邮票。集合,作为位字段的Enum类型,作为属性集合的静态类(行为类似于集合)以及其他一些可能出现的边缘情况,在这里我会使用复数名称。
URL是资源的地址,因此名称为Uniform Resource Locator。我不同意“路线就是查询”。路由可以包含查询(查询字符串)以缩小返回资源的范围,但是路由是所请求的位置或资源。
随着属性路由的出现,为控制器添加多个路由就像[RoutePrefix("quotes")]在QuoteController声明中添加属性一样容易。这也使关联路线的设计更加容易。查看原始问题中提供的示例路线:
/quotes
GET: Gets all quotes
POST: Creates a new quote
/authors/shakespeare/quotes
Associative route in the QuoteController
GET: Gets all Shakespeare quotes
/quotes/new
This is a bad route IMO. Avoid verbs.
Make a POST request to '/api/quotes' to create a new quote
/quotes/shakespeare
/quotes/popular
Although these would be nice to have, they're not practical for routing (see below)
最后两条路由的问题在于,您没有一种简单的方法来区分流行报价和作者报价,更不用说通过名称或ID链接到报价的路由了。您将需要用修饰的动作([Route("popular")]后跟[Route("{author}")](以该顺序)),以使路由表以适当的顺序拾取路由。但是作者的路线消除了使用[Route("{quoteName}")]或的可能性[Route("{quoteId}")](假设quoteId是一个字符串)。自然地,您将希望能够按名称和/或ID路由到报价。
最好通过关联的方式获得作者的报价。您仍然可以将流行的路由作为静态路由名称使用,但是此时您正在增加路由复杂性,这将更适合于查询字符串。如果我真的想在路线中使用受欢迎的搜索字词,这就是我的脑海:
a:/authors/{authorName}/quotes
b:/authors/{authorName}/quotes/popular
c:/authors/{authorName}/quotes?popular=true
d:/quotes/popular
e:/quotes/popular?author={authorName}
f:/quotes?author={authorName}&popular=true
g:/quotes/{quoteName|quoteId}
这些可能会分散到QuoteController的操作中。假设控制器具有一个[RoutePrefix("quotes")]属性:
[HttpGet]
[Route("popular")]
[Route("~/authors/{authorName}/quotes/popular")]
// Handles routes b, d, & e
public ViewResult GetPopularQuotes(string authorName)
return GetQuotes(authorName, true);
[HttpGet]
[Route("")]
[Route("~/authors/{authorName}/quotes")
// Handles routes a, c, & f
public ViewResult GetQuotes(string authorName, bool popular = false)
// TODO: Write logic to get quotes filtered by authorName (if provided)
// If popular flag, only include popular quotes
[HttpGet]
[Route("{quoteId}")]
// Handles route g
public ViewResult GetQuoteById(string quoteId)
// TODO: Write logic to get a single quote by ID
免责声明:我将这些属性写在了脑海中,可能需要消除一些细微的差异,但是希望能够掌握这些路线的要点。
希望这有助于消除对控制器主题的困惑,并根据命名约定路由最佳实践。最终,使用复数或单数控制器或路由的决定取决于开发人员。无论如何,一旦选择了最佳做法,请保持一致。