2010-08-19 91 views
3

我正嘗試以編程方式登錄本網站https://www.virginmobile.com.au(右側有一個會員登錄表單)。C#HttpWebRequest HTTPS失敗

該表單有效。但是,當我對錶單操作(https://www.virginmobile.com.au/selfcare/MyAccount/LogoutLoginPre.jsp)發出POST請求時,它失敗了。

它返回一個302,然後跟進到新的位置,它會返回405

這是我的代碼test1.aspx.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Net; 
using System.Text; 
using System.IO; 
using System.Security.Cryptography.X509Certificates; 
using System.Net; 


public partial class test1 : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
    string uri = "https://www.virginmobile.com.au/selfcare/MyAccount/LogoutLoginPre.jsp"; 
    string parameters = "username=0411222333&password=123"; 

    System.Net.ServicePointManager.CertificatePolicy = new MyPolicy(); 

    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri); 
    req.Method = "POST"; 
    req.ContentType = "application/x-www-form-urlencoded"; 
    //req.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2 (.NET CLR 3.0.4506.2152)"; 
    //req.Referer = "http://www.virginmobile.com.au/"; 
    //req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; 
    req.AllowAutoRedirect = false; 

    // Send the Post 
    byte[] paramBytes = Encoding.ASCII.GetBytes(parameters); 
    req.ContentLength = paramBytes.Length; 
    Stream reqStream = req.GetRequestStream(); 
    reqStream.Write(paramBytes, 0, paramBytes.Length); //Send it 
    reqStream.Close(); 

    // Get the response 
    HttpWebResponse response = (HttpWebResponse)req.GetResponse(); 
    if (response == null) throw new Exception("Response is null"); 

    if (!string.IsNullOrEmpty(response.Headers["Location"])) 
    { 
     string newLocation = response.Headers["Location"]; 

     // Request the new location 
     req = (HttpWebRequest)WebRequest.Create(newLocation); 
     req.Method = "POST"; 
     req.ContentType = "application/x-www-form-urlencoded"; 
     //req.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2 (.NET CLR 3.0.4506.2152)"; 
     //req.Referer = "http://www.virginmobile.com.au/"; 
     //req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; 
     req.AllowAutoRedirect = false; 
     req.CookieContainer = new CookieContainer(); 
     req.CookieContainer.Add(response.Cookies); 

     // Send the Post 
     paramBytes = Encoding.ASCII.GetBytes(parameters); 
     req.ContentLength = paramBytes.Length; 
     reqStream = req.GetRequestStream(); 
     reqStream.Write(paramBytes, 0, paramBytes.Length); //Send it 
     reqStream.Close(); 

     // Get the response 
     response = (HttpWebResponse)req.GetResponse(); //**** 405 Method Not Allowed here 
    } 

    StreamReader sr = new StreamReader(response.GetResponseStream()); 
    string responseHtml = sr.ReadToEnd().Trim(); 

    Response.Write(responseHtml); 
    } 
} 

public class MyPolicy : ICertificatePolicy 
{ 
    public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) 
    { 
    return true; // Return true to force the certificate to be accepted. 
    } 
} 

誰能幫助我?提前致謝!

回答

5

302響應正試圖將您重定向到另一個頁面,所以問題可能是您的POST數據未被髮送到重定向頁面。

也許嘗試設置HttpWebRequest.AllowAutoRedirect = false並捕獲您獲得 的異常。然後向重定向的URL創建另一個請求(在位置響應頭中指定),然後使用相同的POST數據再次發出請求。

+0

使用TamperData,我發現在virginmobile.com.au真正形成還重定向...但我想試試。謝謝! – Aximili 2010-08-20 01:59:47

+0

它似乎設置了一個cookie。你如何獲得使用C#的「位置」? – Aximili 2010-08-20 02:15:07

+1

調用GetResponse()後,您可以在WebResponse.Headers屬性中找到響應標頭。您可以使用'request.CookieContainer = new CookieContainer();'來捕獲cookie。 – 2010-08-20 02:18:31

1

您發送的請求只有很少的標題。他們很可能寫了他們的腳本,以便期望某些標題出現。我能想到的把我的頭頂部標題是:

  • User-Agent(識別您的瀏覽器和版本,你可以假裝是火狐等)
  • Referer(識別您來自的URL;把主頁網址在這裏)
  • Accept-CharsetAccept-EncodingAccept-Language

但也有可能是其他。您可以使用您提到的Fiddler工具來找出Firefox(或您使用的任何瀏覽器)使用正常(非HTTPS)請求發送的頭文件,然後將其中的一些添加到您的請求中,並查看它是否能夠正常工作。 (就個人而言,我用TamperData用於此目的,這是一個Firefox插件。)

+0

感謝Timwi,TamperData很不錯。它似乎設置了一個cookie。任何想法如何以編程方式捕獲cookie並將它傳遞給下一個請求(在Location中指定)? – Aximili 2010-08-20 02:14:41

+0

哈哈!我真的沒想到你沒有照顧最明顯的標題,Cookie。您認爲登錄是如何工作的? :) - 我懷疑你需要做的就是實例化一個'CookieContainer',並將它分配給'req.CookieContainer'以滿足每一個請求。我還沒有嘗試過,但我期望第一個請求會將cookie存儲在那裏,第二個請求會從中讀取它。 – Timwi 2010-08-20 02:17:02

+0

哈哈我沒有想到這一點。謝謝你可能是對的我會試試看! – Aximili 2010-08-20 02:54:28

0

解決:405是因爲我發送POST而不是GET

1

我得到一個404錯誤 - 遠程服務器返回錯誤:(404)未找到。下面是代碼,我得到的錯誤在相同的代碼行中,你得到405錯誤。如果我用先前的版本替換代碼,則不返回404,但會返回405錯誤。

感謝

string uri = "https://www.virginmobile.com.au/selfcare/MyAccount/LogoutLoginPre.jsp?username=0466651800&password=160392"; 
string parameters = "username=0411223344&password=123456"; 

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri); 
req.Method = "GET"; 
req.ContentType = "application/x-www-form-urlencoded"; 
//req.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.2)  Gecko/20100316 Firefox/3.6.2 (.NET CLR 3.0.4506.2152)"; 
//req.Referer = "http://www.virginmobile.com.au/"; 
//req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; 
req.AllowAutoRedirect = false; 

// Send the Post 
byte[] paramBytes = Encoding.ASCII.GetBytes(parameters); 
//req.ContentLength = paramBytes.Length 
//Dim reqStream As Stream = req.GetRequestStream() 
//reqStream.Write(paramBytes, 0, paramBytes.Length) 
//Send it 
//reqStream.Close() 

// Get the response 
HttpWebResponse response__1 = (HttpWebResponse)req.GetResponse(); 
if (response__1 == null) { 
throw new Exception("Response is null"); 
} 

if (!string.IsNullOrEmpty(response__1.Headers("Location"))) { 
string newLocation = response__1.Headers("Location"); 

// Request the new location 
req = (HttpWebRequest)WebRequest.Create(newLocation + "?" + parameters); 
req.Method = "GET"; 
req.ContentType = "application/x-www-form-urlencoded"; 
req.AllowAutoRedirect = false; 
req.CookieContainer = new CookieContainer(); 
req.CookieContainer.Add(response__1.Cookies); 

// Send the Post 
//paramBytes = Encoding.ASCII.GetBytes(parameters) 
//req.ContentLength = paramBytes.Length 
//Dim reqStream As Stream = req.GetRequestStream() 
//reqStream.Write(paramBytes, 0, paramBytes.Length) 
//Send it 
//reqStream.Close() 

// Get the response 
//**** The remote server returned an error: (404) Not Found. 
response__1 = (HttpWebResponse)req.GetResponse(); 
} 

StreamReader sr = new StreamReader(response__1.GetResponseStream()); 
string responseHtml = sr.ReadToEnd().Trim();