C# Persistent WebClient
I have a class written in C# (Windows Forms)
It's a WebClient class which I intent to use in some website and for Logging In and navigation.
Here's the complete class pastebin.com (the class has 197 lines so I just use pastebin. Sorry if I made a little bit harder for you to read the c开发者_如何学JAVAlass, also below this post)
The problem is, am not sure why it's not persistent .. I was able to log in, but when I navigate to other page (without leaving the domain), I was thrown back to log in page.
Can you help me solving this problem?
one issue though is, the site I was trying to connect is "HTTPS" protocol. I have not yet tested this on just a regular HTTP.
Thank you in advance.
/*
* Web Client v1.2
* ---------------
* Date: 12/17/2010
* author: Jayson Ragasa
*/
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Web;
namespace Nullstring.Modules.WebClient
{
public class WebClientLibrary
{
#region vars
string _method = string.Empty;
ArrayList _params;
CookieContainer cookieko;
HttpWebRequest req = null;
HttpWebResponse resp = null;
Uri uri = null;
#endregion
#region properties
public string Method
{
set { _method = value; }
}
#endregion
#region constructor
public WebClientLibrary()
{
_method = "GET";
_params = new ArrayList();
cookieko = new CookieContainer();
}
#endregion
#region methods
public void ClearParameter()
{
_params.Clear();
}
public void AddParameter(string key, string value)
{
_params.Add(string.Format("{0}={1}", WebTools.URLEncodeString(key), WebTools.URLEncodeString(value)));
}
public string GetResponse(string URL)
{
StringBuilder response = new StringBuilder();
#region create web request
{
uri = new Uri(URL);
req = (HttpWebRequest)WebRequest.Create(URL);
req.Method = "GET";
req.GetLifetimeService();
}
#endregion
#region get web response
{
resp = (HttpWebResponse)req.GetResponse();
Stream resStream = resp.GetResponseStream();
int bytesReceived = 0;
string tempString = null;
int count = 0;
byte[] buf = new byte[8192];
do
{
count = resStream.Read(buf, 0, buf.Length);
if (count != 0)
{
bytesReceived += count;
tempString = Encoding.UTF8.GetString(buf, 0, count);
response.Append(tempString);
}
}
while (count > 0);
}
#endregion
return response.ToString();
}
public string GetResponse(string URL, bool HasParams)
{
StringBuilder response = new StringBuilder();
#region create web request
{
uri = new Uri(URL);
req = (HttpWebRequest)WebRequest.Create(URL);
req.MaximumAutomaticRedirections = 20;
req.AllowAutoRedirect = true;
req.Method = this._method;
req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
req.KeepAlive = true;
req.CookieContainer = this.cookieko;
req.UserAgent = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/534.10";
}
#endregion
#region build post data
{
if (HasParams)
{
if (this._method.ToUpper() == "POST")
{
string Parameters = String.Join("&", (String[])this._params.ToArray(typeof(string)));
UTF8Encoding encoding = new UTF8Encoding();
byte[] loginDataBytes = encoding.GetBytes(Parameters);
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = loginDataBytes.Length;
Stream stream = req.GetRequestStream();
stream.Write(loginDataBytes, 0, loginDataBytes.Length);
stream.Close();
}
}
}
#endregion
#region get web response
{
resp = (HttpWebResponse)req.GetResponse();
Stream resStream = resp.GetResponseStream();
int bytesReceived = 0;
string tempString = null;
int count = 0;
byte[] buf = new byte[8192];
do
{
count = resStream.Read(buf, 0, buf.Length);
if (count != 0)
{
bytesReceived += count;
tempString = Encoding.UTF8.GetString(buf, 0, count);
response.Append(tempString);
}
}
while (count > 0);
}
#endregion
return response.ToString();
}
#endregion
}
public class WebTools
{
public static string EncodeString(string str)
{
return HttpUtility.HtmlEncode(str);
}
public static string DecodeString(string str)
{
return HttpUtility.HtmlDecode(str);
}
public static string URLEncodeString(string str)
{
return HttpUtility.UrlEncode(str);
}
public static string URLDecodeString(string str)
{
return HttpUtility.UrlDecode(str);
}
}
}
UPDATE Dec 22GetResponse overload
public string GetResponse(string URL)
{
StringBuilder response = new StringBuilder();
#region create web request
{
//uri = new Uri(URL);
req = (HttpWebRequest)WebRequest.Create(URL);
req.Method = "GET";
req.CookieContainer = this.cookieko;
}
#endregion
#region get web response
{
resp = (HttpWebResponse)req.GetResponse();
Stream resStream = resp.GetResponseStream();
int bytesReceived = 0;
string tempString = null;
int count = 0;
byte[] buf = new byte[8192];
do
{
count = resStream.Read(buf, 0, buf.Length);
if (count != 0)
{
bytesReceived += count;
tempString = Encoding.UTF8.GetString(buf, 0, count);
response.Append(tempString);
}
}
while (count > 0);
}
#endregion
return response.ToString();
}
But still I got thrown back to login page.
UPDATE: Dec 23
I tried listing the cookie and here's what I getat first, I have to login to a webform and this I have this Cookie JSESSIONID=368C0AC47305282CBCE7A566567D2942
then I navigated to another page (but on the same domain) I got a different Cooke? JSESSIONID=9FA2D64DA7669155B9120790B40A592C
What went wrong? I use the code updated last Dec 22
You need to use the CookieContainer in the first GetResponse
overload.
If you are navigating to the second page using the GetResponse(string URL) override, it does not attach the cookie container to the request, thus the session cookie (which usually contains the auth token) from the login request is not passed to the server. Hence the server does not know that you already logged in.
Change your code to attach the cookie container to all the requests, and it should work.
Alternatively, see if the web server accepts login from cookie-less clients (by sending the session info in a URL parameter) and change your code to use that approach.
精彩评论