2010-08-19 157 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();