为什么 HttpRequest.HttpMethod 是字符串而不是枚举?

27

在 .NET Framework 的 HttpRequest.HttpMethod 参考中,请求类型是用 System.String 类型声明的。

RFC 2616 中声明了所有的 HTTP 请求方法(例如 POST、GET、PUT、DELETE ...)。

.NET 的 HttpWebRequestWebRequest 类也有类似的行为。

Java 在 HttpURLConnection#setRequestMethod(String) 方法上也有类似的方法。

为什么这些语言设计者没有考虑为这些 HTTP 方法实现一个枚举呢?

你有想法吗?

4个回答

37
你所引用的RFC 2616链接中的第一句话如下(强调添加):
“HTTP/1.1的常见方法集在下面定义。尽管可以扩展此集合...”
也就是说,HTTP中的方法可以是任何内容。有“众所周知”或者常见的方法,其语义已经很好理解了(嗯,好吧,应该被理解 - 我仍然会遇到不清楚GET / POST的人)。
但是任何应用程序都可以实现其他方法。希望客户端和服务器应用程序之间理解那些其他方法的语义。
因此,使用枚举类型将不合适,因为始终可能有无法适应该枚举类型的“其他”值。
更多来自RFC 2616的引文如下:
“实际的信息系统需要比简单检索更多的功能,包括搜索、前端更新和注释。HTTP允许一个开放式的方法和头,以指示请求的目的。”
以及,
“Method令牌表示要在Request-URI标识的资源上执行的方法。该方法区分大小写。”
   Method         = "OPTIONS"                ; Section 9.2
                  | "GET"                    ; Section 9.3
                  | "HEAD"                   ; Section 9.4
                  | "POST"                   ; Section 9.5
                  | "PUT"                    ; Section 9.6
                  | "DELETE"                 ; Section 9.7
                  | "TRACE"                  ; Section 9.8
                  | "CONNECT"                ; Section 9.9
                  | extension-method
   extension-method = token

我同意,但是当你看 System.Web.Mvc.HttpVerbs 枚举时,我有点迷惑。这是好事还是坏事?此外,我认为将此枚举放在命名空间 System.Web.Mvc 下是一个错误的决定,无论如何。 - liuhongbo
@liuhongbo - 我在Mvc命名空间中看到的每个地方,它们似乎都支持两个重载 - 一个接受此枚举的值,另一个接受字符串(或字符串数组)。这是一种不同的做法,但他们似乎仍然需要提供一个逃生口,以便当方法不在常用集合中时使用。 - Damien_The_Unbeliever
作为回答的例子,PATCH不在HttpMethod方法列表中。 - jordiburgos

3
如果HTTP引入了一种新方法,那么java和C#需要更新他们的枚举。他们将何时更新呢?他们会发布一个补丁吗?还是在下一个版本中更新?因此,在不能控制值的情况下定义枚举不是一个明智的决定。

3
怎么比较呢?我并不是在比较HTTP和枚举类型。这就像比较香蕉和高中学生一样。你的回答没有解释性。 - ahmet alp balkan
而且为了扩展答案,这些方法可以被扩展,那么谁来维护这个枚举库呢? - Ajay Bhosale
我仍然无法从你的评论中得到任何东西。 - ahmet alp balkan
3
如果HTTP出现了新的方法,那么Java和C#需要更新它们的枚举。他们将在什么时候更新?他们会发布补丁吗?还是会在下一个版本中更新?因此,在不能控制其值的情况下定义枚举并不是一个明智的决定... - Ajay Bhosale

3
该规范明确允许使用更多的方法,因此所有方法的集合不能被枚举。

2
正如Damien所提到的,RFC2616仅定义了通用方法。HTTP和XML一样,是一种可以扩展以支持其他格式的协议。
例如,假设我想实现一个名为“Encrypt”的特殊方法。如果HTTP库是枚举类型,它将失败并可能抛出异常。当然,客户端必须知道这个特殊请求类型,这就是为什么大多数扩展是通过标头而不是命令来完成的。
HTTP是一种可扩展的协议,但很少有人真正进行扩展。
考虑这个简单的例子:
<form method="Foo" action="http://someurl"></form>

由于“method”只是文本,用户可以在那里输入任何内容,那么HTTP处理程序必须能够处理它,对吗?

编辑:

事实证明,HTML 4规范只允许GET和POST成为有效值,但HTTP超越了这一点。


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