405 - 方法不允许HttpWebRequest

时间:2012-04-02 14:00:55

标签: vb.net http-headers httpwebrequest http-status-code-405

尝试发送POST请求时遇到问题。发送方法如下所示:

Public Sub SendXML(ByVal file As String)
    Dim reader As New StreamReader(file)
    Dim data As String = reader.ReadToEnd()
    reader.Close()
    Dim request As HttpWebRequest = WebRequest.Create("http://blah/Request")
    request.Method = "POST"

    System.Net.ServicePointManager.Expect100Continue = False

    Dim bytes As Byte() = System.Text.Encoding.ASCII.GetBytes(data)
    request.ContentLength = bytes.Length

    Dim oStreamOut As Stream = request.GetRequestStream()
    oStreamOut.Write(bytes, 0, bytes.Length)
    oStreamOut.Close()

    Dim response As HttpWebResponse = request.GetResponse()

End Sub

运行时我得到上述错误。通过Fiddler我可以看到请求看起来像:

POST http://blah/Request HTTP/1.1
Host: blah
Content-Length: 322
Proxy-Connection: Keep-Alive

<?xml version="1.0"?>
<Envelope>
<Header>
<UserID>uid</UserID>
<Password>pass</Password>
<SessionID />
<RequestType>GetDetails</RequestType>
<POSCompany>01</POSCompany>
<PackageType>DATA</PackageType>
<ActionType>READ</ActionType>
<SnoopUserID />
</Header>
<Body>
<MagicNumber>124</MagicNumber>
</Body>
</Envelope>

现在看着这个我怀疑这是因为服务器不接受POST消息。但是其他一些说法表明,URI http://blah/Request已使用代理生成,应为/Request,因此该行应为POST /Request HTTP/1.1

那么这个的常见原因是什么?如果它是代理问题,它是如何排序的?

如下所述,我为更具体的请求创建了一个新问题。 Changing absolute URI to relative in HTTP POST header

3 个答案:

答案 0 :(得分:1)

POST请求没有任何问题,因此问题必须在其他地方。

沿途还有很多其他地方可能会造成麻烦:

  1. 您和正在更改HTTP方法的服务器之间可能存在错误的代理
  2. 服务器可能出现故障或根本没有支持POST
  3. 然而,我的猜测是,服务器不仅仅是查看HTTP方法,而是为了响应XML负载正在包装的RPC调用而给出405错误。

    某些RPC服务器将(错误地)使用这样的HTTP状态代码来指示无法执行所请求的方法,或者说具有权限和安全性的请求的其他内容是错误的。

    如果服务器稍微表现得更好(而且你很幸运),那么在响应正文中返回可能指示405错误即将发生的地方的其他信息从

答案 1 :(得分:0)

您是否遗漏了Content-Type所需的POST标头? 有关详细信息,请阅读here。 我认为这是强制性的。

答案 2 :(得分:0)

您的POST似乎完全无效。 POST数据应该被编码(即,作为multipart / form-data)并使用正确的内容类型(即application / x-www-form-urlencoded)以及正确的编码和边界等。您只是发送服务器a文本块,我并不感到惊讶它翻了出来。

我不是100%确定VB在幕后做了什么,但是this MSDN page建议您需要将内容类型设置为支持的方法,并且您的标题中也可能需要Content-Disposition: form-data 。我发现an example执行此操作并添加了MIME边界:

string FileData = "this is test file data\r\n"; // test data to send.
StringBuilder DataString = new StringBuilder();
DataString.Append(dataBoundary + "\r\n");
//This sends the viewstate info
DataString.Append("Content-Disposition: form-data; name=" + HiddenValue
+ "\r\n"
+ dataBoundary + "\r\n");
DataString.Append("Content-Disposition: form-data; name=" + "\"" +
"File1" +
"\"" +
"; filename=" + "\"" + "TestFile3.txt" + "\"" + "\r\n");
DataString.Append("Content-Type: text/plain\r\n\r\n");
DataString.Append(FileData);
DataString.Append(dataBoundary + "\r\n");
DataString.Append("Content-Disposition: form-data; name=" + "\"" +
"Submit1" +
"\"" + "\r\n\r\n" + "Upload\r\n" + dataBoundary + "--\r\n");

该示例模拟文件字段上载。

对于更简单的版本,您可以将request.ContentType = "application/x-www-form-urlencoded"与URL编码数据一起使用,例如:Dim postData As String = "myURL=http%3A%2F%2Fexample.com%2Findex.php"。请注意,格式为key=value,数据必须首先进行URL编码。

我不确定你究竟需要什么,因为很多东西取决于远程服务器实际对表单和字段名称的期望。它还取决于服务器实际上是否遵循相关的HTML标准和RFC。您是否有可用的HTML表单作为服务器期望的指南?