asp.net 处理单个和多个控制器/路由

yizd12fk  于 2023-05-02  发布在  .NET
关注(0)|答案(4)|浏览(168)

我有点困惑,我应该如何处理我的web应用程序中的单数和复数路由和控制器。
该网站是一个简单的报价网站-想想爱因斯坦,莎士比亚等。不是保险。在项目中,我有一个名为“QuoteController”的控制器。控制器名称是单数的,这是否意味着控制器应该只处理单引号的显示?即

/quote/love-is-a-battlefield-1

那么,我是否需要另一个控制器来显示多个引号(复数)?例如:

/quotes/ (would default to most recent)
/quotes/new
/quotes/shakespeare
/quotes/popular

为单数和复数路由使用单独的控制器是惯例还是良好做法?我希望这是有意义的。

azpvetkf

azpvetkf1#

仅仅因为asp-mvc的默认控制器有单数名称,并不意味着你应该为所有的控制器实现单数形式。

**正确答案为:**取决于您的控制器所代表的资源的默认数量。
单数,例如AccountController是单数,因为它只表示与单个帐户有关的操作(操作方法)。
Plural如果您的控制器包含至少一个action方法,该方法可以在一个请求中处理多个资源。
复数格式示例

users/update/3

上面的路线让你认为你在编辑所有用户,如果你把它读成一个句子,这是没有意义的。但是,如果你像查询一样阅读你的路线,它会有意义得多。
如果我们考虑一下,路由就是一个查询:{resource}/{action}/{parameter}看起来像一个查询。
users/all的简写为 “选择所有用户表”
users/123读取 “从用户表中选择单个实体”
users/update/123读取 “update single entity from users table”

主要网站使用复数格式,见下面的示例

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)

我认为英语语法应该严格地融入到每一个编程方面。它读起来更自然,并导致良好的代码卫生。

wribegjk

wribegjk2#

回答

下面是程序员在StackExchange中提出的一个question问题,建议保持类名的单数。我特别喜欢其中一个答案中的逻辑,“拧螺丝的工具叫“螺丝刀”而不是“螺丝刀”。”””我同意。名称应保留为名词和形容词。
就路由而言,最佳实践似乎倾向于路由是复数名词,并避免使用动词。Apigee blog说,
“避免混合模型,其中一些资源使用单数,另一些使用复数。一致性允许开发人员在学习使用API时预测和猜测方法调用。“* 并建议根据流行网站的做法使用单数或复数。他们在路由中使用 * 单数 * 名词的唯一例子是Zappos网站,它有http://www.zappos.com/Product作为路由;但是如果你仔细检查这个网站,它并不是一个指向某个产品资源的路径,而是一个查询,可能是针对他们所有的产品。您可以输入http://www.zappos.com/anything并获得结果页面。所以我不会太相信。
其他的博客,比如mwaysolutions的this(random find)说 “使用名词而不是动词”“使用复数名词”。除此之外,大多数博客/文章都倾向于说同样的事情。复数名词,没有动词。

**TL;DR:**控制器使用单数名词,路由使用复数名词。

控制器

控制器和路由代表两个不同的概念。控制器是一个类,或者说是一个蓝图。类似于邮票,我不会说我有一个UnicornsStamper,我会说我有一个UnicornStamper,使一个独角兽的邮票,我可以使一个收集的独角兽邮票。集合、作为位字段的枚举类型、作为属性集合的静态类(类似于集合),可能还有一些其他的边缘情况,我会使用复数名称。

路由

URL是资源的地址,因此名称为 Uniform Resource Locator。我不同意 “路线查询”。路由可以包含查询(query string)来缩小返回资源的范围,但路由是所请求的位置或资源。
随着属性路由的出现,控制器的路由的复数化就像在QuoteController声明中添加[RoutePrefix("quotes")]属性一样简单。这还允许更容易地设计关联管线。查看原题中提供的示例路线:
/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路由到引号。

有点跑题

按作者获取引用最好通过关联路由来完成。您仍然可以使用 popular 路由作为静态路由名,但此时您正在增加路由复杂性,这将更适合于查询字符串。在我的脑海中,这是我如何设计这些路线,如果我真的想在路线中有 * 热门 * 搜索词:
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

**免责声明:**我写下了这些属性,可能有一些小的差异需要解决,但希望要点如何让这些路由工作。

希望这有助于澄清关于控制器和命名约定的路由最佳实践的一些困惑。最终,使用复数或单数控制器或路由的决定取决于开发人员。无论如何,一旦你选择了一个最佳实践,就要保持一致。

h4cxqtbf

h4cxqtbf3#

控制器的名称可以是复数或单数,具体取决于其执行的逻辑。最有可能的是,我们将控制器名称保持为单数,因为ProductController听起来比ProductsController好一点。

/product/list    or    /products/list
   /product/add   or    /products/add

你可以两个都用。但你必须保持一致性,你不应该混合它们。对于每个实体类型,所有URL都应该是复数,或者都应该是单数。
在ASP.NET示例中,他们使用了单一控制器名称,如HomeController、AccountController。在HomeController的情况下,您不能使用HomesController,因为它不再代表当前站点Home。
关于逻辑,我们通常为每个数据库实体创建控制器,其中我们推断控制器表示要在“实体”上执行的操作,因此使用单数控制器名称是很好的,没有害处。
只有当你想创建一组控制器来表示一些看起来像或Map到多个数据库表名的东西的集合时,你才可以将其命名为复数。

q8l4jmvw

q8l4jmvw4#

问得好这个网站的一些贡献者会建议你尝试Programmers网站,但我愿意尝试回答你的问题。
ASP.NET MVC在概念上是基于Resource-oriented architecture的;罗阿权一般准则是
应用程序应该公开许多URI(可能有无限多个),每个URI对应一个Resource(应用程序中的任何资源都应该通过唯一的URI明确访问)
因此,由您决定quotequotes是否是两个不同的资源。

相关问题