什么是 ASP.NET MVC 的 RESTful?

Posted

技术标签:

【中文标题】什么是 ASP.NET MVC 的 RESTful?【英文标题】:What's so RESTful about ASP.NET MVC? 【发布时间】:2011-04-13 10:42:51 【问题描述】:

REST 在过去几年(左右)一直是一个非常流行的流行语,当 ASP.NET MVC 推出时,每个人都将 REST 与 ASP.NET MVC 联系起来。我也很喜欢这种嗡嗡声,由于我缺乏知识,我对 REST 的理解只是:

REST = SEO/用户友好的 URL

但它远不止于此。我对 REST 了解得越多,我就越少将 ASP.NET MVC 与它联系起来。它当然比 WebForms 更接近 REST。所以事实其实恰恰相反:

REST ≠ SEO/用户友好的 URL

将默认路由定义为controller/action/id绝对不是 RESTful。

让我解释一下我对这种理解的问题。

如果 ASP.NET MVC 是 RESTful,我们不会将默认路由定义为:

controller/action/id

而是

resources/id  /* that would have to use HTTP methods GET/PUT/POST/DELETE */

所以不要有(也提供带有请求路径的HTTP方法):

/product/index/1  /* GET */
/product/create   /* POST */
/product/delete/1 /* POST */
/product/update/1 /* POST */

应该是(这里也提供了HTTP方法)

/products/1  /* GET */
/products    /* POST */
/products/1  /* DELETE */
/products/1  /* PUT */

现在这将是 RESTful。 好消息是这实际上是可能的。如果你让它完全 RESTful,那也意味着你将必须使用 Ajax,因为 PUT 和 DELETE 方法不能用于仅浏览器的请求(这并不完全正确1)。因此,现代 Ajax 应用程序实际上可以完全是 RESTful。

Ajax 是客户端技术,与 ASP.NET MVC 没有任何关系。事实上,ASP.NET MVC 可以作为一个完全 RESTful 应用程序来完成。实现它的手段(Ajax)并不重要。 (感谢 Darin Dimitrov)

主要问题

为什么我们将 ASP.NET MVC 视为一个 RESTful 框架,尤其是与它的 URL 路由相关联?他们为什么不定义默认 URL 路由来强制 RESTful?我不是在寻找有争议的答案,而是那些真正回答问题的答案 - 这种关系是如何产生的......也许我仍然不够聪明,仍然认为这是我对两者缺乏了解。

1更新信息

实际上,您不必使用 Ajax 来实现完全 RESTful 架构。 Asp.net MVC 支持(从版本 2 开始)HTTP 方法覆盖,这意味着您可以使用浏览器表单发出 PUT 或 DELETE 方法。您所要做的就是添加一个额外的隐藏字段,例如:

<input type="hidden" name="X-HTTP-Method-Override" value="DELETE" />

Asp.net MVC 框架将能够将 POST 请求理解为 DELETE 请求,HttpDeleteAttribute 操作方法选择器也将其理解为删除请求。覆盖 FTW 的 HTTP 方法!

【问题讨论】:

超链接会导致 GET,而表单会提交 POST,因此除非用 AJAX 之类的东西替换它们,否则无法通过正常的浏览器操作使用 DELETE 和 PUT。 @Andrew:我在几分钟前的问题中也说过同样的话。我同意。 @Andrew,但这不一定是真的,是吗?我想你可以指定你的表单方法也可以是 GET ,对吧? @DaveDev,不是浏览器限制。 @Robert & @Darin,所以如果是浏览器限制,你真的不能责怪 ASP.NET MVC 必须异步提交 DELETE 和 PUT 请求吗? 【参考方案1】:

这个问题有点过时了,现在 (2014-08) 的答案是这样的:ASP.NET MVC 允许 RESTful URL 方案,但不是这样设计的,因此这是默认设置。相反,ASP.NET MVC 的成功之处在于更传统的 Controller+Action 风格的 MVC。

现在编写 RESTful 服务的 ASP.NET 方式是 ASP.NET Web API。这使得通过使用与 HTTP 动词匹配的方法命名约定来创建 RESTful URL 方案变得更加容易。

请注意,一旦当前称为 ASP.NET vNext 的内容发布,此答案将过时,其中 Web API 和 MVC 合二为一。

【讨论】:

【参考方案2】:

项目经理:“让我们完全 RESTful 开发我们的新项目!!!”

其他程序员大喊:“YAyyyyyy!!!”

    几周后的开发阶段:“先生,我们需要让客户端能够同时更新多行,因此我们需要做一个解决方法”

    “先生,我只需要获取最新的发票”

    “先生,我必须传页码和大小!”

真可惜。我们为什么不都回到 XML RPC

【讨论】:

AD1:没问题。只要您发布一组特定实体,它仍然适用。服务器端应该检测到并做必要的事情。 AD2:使用查询变量www.example.com/products?latestAD3:同样适用。查询变量:www.example.com/products?page=2&amp;size=15。添加任何其他以及即。过滤条件或排序属性 ASP.NET Web API OData 控制器也可以很容易地解决问题二和三。非常强大。【参考方案3】:

没有 URI 样式可以让 API 变得安静。

您问:“为什么我们将 ASP.NET MVC 视为一个 RESTful 框架,尤其是与它的 URL 路由相关?”

因为 REST 被误解为关于 URL 而不是关于 resources, a standard interface, and hypermedia。

【讨论】:

这是迄今为止对这个问题最好的回答。 但是,有一种 URI 样式使 API 不稳定。具体来说,如果 URI 不对应于资源。 我会说这更多的是 URI 识别的特征,而不是它的“样式”——当我说样式时,我指的是 URI 中的字符模式。但可以肯定的是,它们应该对应于资源。 如果URI“样式”仅表示字符,那么您当然是对的。我的解释是 - 类似于上面的地址(/x/create/1/x/update/1,...) - URI 本身带有一些语义内涵,因此您应该从另一个计算一个 URI,而不是使用 HTTP动词并将相关动作编码为嵌入在表示中的 URI(超媒体约束)。在后一种情况下,系统是不稳定的。【参考方案4】:

我只是想为关于 PUT 和 DELETE 的使用的 REST 讨论做出贡献。

一般在 REST 和其他 RESTful 框架中,PUT 和 DELETE 的问题并不能通过制作诸如 resource/createresource/delete 之类的 URL 来解决。相反,动词通过 POST 被隧道化:

    html 表单中传递隐藏的输入,例如 _method。 使用 javascript 执行 PUT 或 DELETE 要克服某些防火墙,您可能需要使用 HTTP X-HTTP-Method-Override 标头。

这是针对 HTTP 方法问题的通用解决方案。

我不知道 ASP.Net 为何不采用这种方式,但是像 /product/delete/1 这样的 URL 不提供 RESTful 资源。

编辑:似乎有必要澄清一下什么是 REST。 From the horse's mouth:

REST API 不应包含对通信协议的任何更改,除了填写或修复标准协议的未指定位的详细信息,例如 HTTP 的 PATCH 方法或 Link 标头字段。对损坏的实现(比如那些愚蠢到认为 HTML 定义了 HTTP 的方法集的浏览器)的解决方法应该单独定义,或者至少在附录中定义,并期望该解决方法最终会过时。 [这里的失败意味着资源接口是特定于对象的,而不是通用的。]

强调我的。 REST 未定义为使用四种 HTTP 方法。它甚至没有被定义为使用 HTTP。它需要一个能够跟踪超链接的通信协议。它使用该协议,在不违反协议的情况下添加了适当的定义。

在 HTTP 的情况下,明确允许对未实现 PUT 和 DELETE 的浏览器使用变通方法。第 1 点中的 Rails 方法显然可以做到这一点。

【讨论】:

Ad1:这不是 RESTful。 POST 不是幂等的……第二个是。只有 Javascript 驱动的客户端才能真正使用完全 RESTful 的服务器应用程序。这就是我的问题的结果。 @Robert: (1) 相当 RESTful,即使 POST 不是幂等的。 REST 并不是要使用这四种方法,as a comment by Roy Fielding, the inventor of REST, shows。我的博士课题主要是关于扩展 REST,所以我知道。另外,请参阅我的评论here。【参考方案5】:

没有什么可以阻止您在 ASP.NET MVC 中使用 HTTP 方法 GET/PUT/POST/DELETE 获得像 resource/id 这样的路由。这不是默认路由设置,但您可以做到。

编辑(MLaritz - 添加达林的评论): ASP.NET MVC 是一种服务器端技术,允许您公开 RESTful url。它们的消费方式无关紧要。您问为什么 ASP.NET MVC 被认为是 RESTFul 技术,答案是因为您可以轻松公开 RESTFul url 以供使用,就这么简单。

【讨论】:

您发布答案时,我正在编辑我的问题。是的 完全 RESTful MVC 应用程序是可能的。我指出了关于 Ajax 的额外观察。 Ajax 是一种客户端脚本技术。它与 REST 无关。 ASP.NET MVC 是一种服务器端技术,允许您公开 RESTful url。它们的消费方式无关紧要。您问为什么 ASP.NET MVC 被认为是 RESTFul 技术,答案是因为您可以轻松公开 RESTFul url 以供使用,就这么简单。 完全正确。但是由于 Asp.net MVC 是一个 Web 框架,其视图将被浏览器使用,所以仍然应该提到 Ajax。但你是对的。 Asp.net MVC 可以完全 RESTful。【参考方案6】:

我认为很多嗡嗡声更多地与 .NET Web 堆栈在 MVC 之前的非 RESTful 以及 MVC 使在 .NET 平台上构建 RESTful 应用程序比任何特别的 RESTful 功能 ASP.NET 更容易有关MVC 有。

【讨论】:

+1 这是迄今为止我的问题最接近的答案。谢谢。【参考方案7】:

This link 可能会启发您的探索……简而言之,您可以拥有像您描述的那样的 Url - 至少在 MVC 2 中是这样。

【讨论】:

我并不是说 MVC 无法实现 RESTful 执行(这在 1.0 中也是可能的你只是没有快捷方式属性),我我只是说他们呈现框架的方式与 REST 关系不大。而且 PUT 和 DELETE 动词只能使用 Ajax FYI 来完成,这意味着只有出色的可用性应用程序才能真正实现 RESTful。 嗯,它真的是关于可能性和设计...... MVC 是一种新的、更结构化的 Web 开发概念,它试图让开发人员的生活更轻松,同时为他提供更多他可以实现的可能性。因此,只要它支持 RESTful URL,恕我直言,它就可以被视为 RESTful——即使营销和简单示例没有立即显示出这种质量。

以上是关于什么是 ASP.NET MVC 的 RESTful?的主要内容,如果未能解决你的问题,请参考以下文章

选择哪一个:ASP.NET MVC 还是 RESTful WCF?

表单身份验证、ASP.NET MVC 和 WCF RESTful 服务

在 .NET 中开发新的 RESTful Web 服务——我应该从哪里开始? ASP.NET-MVC,WCF?

ASP.NET MVC 控制器命名多元化

ASP.NET Web API 从 MVC 4 控制器失败

是否可以使用 maproute 在 asp.net mvc 中路由多个参数