C# HttpWebRequest to a HTTPS failed
I am trying to login to this website https://www.virginmobile.com.au programatically (on the right there is a Member Login form).
That form works. But when I do a POST request to the form action (https://www.virginmobile.com.au/selfcare/MyAccount/LogoutLoginPre.jsp) it failed.
It returns a 302, then following up to the new location, it returns 405.
This is my code 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 = En开发者_高级运维coding.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.
}
}
Could anyone help me? Thanks in advance!
The 302 response is trying to redirect you to another page, so the problem might be that your POST data isn't being sent to the redirected page.
Maybe try setting HttpWebRequest.AllowAutoRedirect = false
and catch the exception that you get
back. Then create another request to the redirected URL (specified in the Location response header) and then issue the request again with the same POST data.
You are sending pretty few headers with your request. It is very possible that they wrote their script so that it expects certain headers to be present. Headers that I can think of off the top of my head are:
User-Agent
(identifies your browser and version; you can pretend to be Firefox, for example)Referer
(identifies the URL you came from; put the homepage URL in here)Accept-Charset
,Accept-Encoding
,Accept-Language
but there may be others. You can probably use the Fiddler tool you mentioned to find out what headers Firefox (or whatever browser you’re using) sends with normal (non-HTTPS) requests and then add some of them to your request and see whether that makes it work. (Personally, I use TamperData for this purpose, which is a Firefox plugin.)
I'm getting a 404 error - The remote server returned an error: (404) Not Found. Below is the code I'm getting the error at the same line of code as you were getting the 405 error. If I replace the code with your previous version no 404 is returned but the 405 error is returned.
Thanks
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();
Resolved: 405 was because I was sending a POST instead of a GET
精彩评论