处理奇异和多个控制器/路由

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)

我相信英语语法应该严格地纳入每个编程方面.它看起来更自然,并导致良好的代码卫生.

  • 我不同意路线是查询。URL 是可以包含查询但本身不是查询的资源位置。我也不会在路由中包含动词。`users/update/123` 应该是对 `users/123` 资源的 PUT 请求。如果在编程的每一个环节都应该严格地结合英语语法,那么所有用户的路由不应该是`/all/users`,更新是`/update/user/123`吗?它不应该是因为路由在语法上并不正确。 (2认同)

nwa*_*yve 9

回答

这是程序员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

免责声明:我将这些属性写在了脑海中,可能需要消除一些细微的差异,但是希望能够掌握这些路线的要点。

希望这有助于消除对控制器主题的困惑,并根据命名约定路由最佳实践。最终,使用复数或单数控制器或路由的决定取决于开发人员。无论如何,一旦选择了最佳做法,请保持一致。


Abb*_*iri 1

好问题。该网站的一些贡献者会建议您尝试程序员网站,但我愿意尝试回答您的问题。

ASP.NET MVC中的路由机制,从概念上来说,是基于面向资源的架构;ROA 的共同准则是

应用程序应该公开许多 URI(可能是无限多个),每个资源对应一个 URI(应用程序中的任何资源都应该可以通过唯一的 URI 明确访问)

因此,由您决定 和 是否quotequotes两种不同的资源。