C# HttpRequester Class (HTTP Request Upload File with POST DATA )

คือผมพยายามลอง Search หา Class ลักษณะนี้แล้วครับ แต่ก็หาไม่ได้สักที เจอแต่อัพโหลดไฟล์ได้อย่างเดียว หรือไม่ก็ POST DATA ได้อย่างเดียว สุดท้ายเลยต้องพยายามเขียนคลาสนี้ขึ้นมาใช้เองครับ

จริงๆ เขียนไว้นานแล้วครับ แต่ไม่แน่ใจว่ามัน bug ตรงไหนรึป่าว เลยเก็บไว้ใช้เองสักพักนึงก่อน ตอนนี้คิดว่าใช้ได้โอเคแล้วครับ จึงนำมาแบ่งปัน

อยากทำอะไรได้มากกว่านี้ ก็นำไปพัฒนาต่อได้เลยนะครับ ถ้าไงส่งตัวพัฒนามาให้ผมก็ดีนะครับ ผมจะได้ใช้ด้วย 🙂

/*
___________________________________________________________________
Name:  HttpRequester Class
Version: 1
Date:  10/06/2008
Author:  Kentreez Jumrus
Description: Make HttpWebRequest with simple command.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Web;
using System.IO;
using System.Collections;

namespace Kentreez
{
	class HttpRequester
	{
		private HttpWebRequest httpWebRequest;
		private Stream requestStream;
		private Stream responseStream;
		private StreamReader responseReader;

		private ArrayList files;
		private ArrayList datas;
		private string sessionKey;
		private string sessionValue;
		private string sessionPath;
		private string sessionDomain;
		private string boundary;
		private string headerFileTemplate;
		private string headerPostDataTemplate;

		private string requestUrl;
		private string encoding;
		private string method;

		public HttpRequester()
		{
			this.files = new ArrayList();
			this.datas = new ArrayList();
			this.encoding = "utf8";
			this.method = "GET";
			this.headerPostDataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
			this.headerFileTemplate = "Content-Disposition: form-data; name=\"{0}\";filename=\"{1}\";\r\n Content-Type: application/octet-stream\r\n\r\n";
		}

		public void SetRequestUrl(string url)
		{
			this.requestUrl = url;
		}

		public void SetCharset(string encoding)
		{
			if (encoding.ToLower().Replace("-", "").Equals("utf7"))
			this.encoding = "utf7";
			else if (encoding.ToLower().Replace("-", "").Equals("utf8"))
			this.encoding = "utf8";
			else if (encoding.ToLower().Replace("-", "").Equals("utf32"))
			this.encoding = "utf32";
			else if (encoding.ToLower().Replace("-", "").Equals("unicode"))
			this.encoding = "unicode";
			else if (encoding.ToLower().Replace("-", "").Equals("bigendianunicode"))
			this.encoding = "bigendianunicode";
			else if (encoding.ToLower().Replace("-", "").Equals("ascii"))
			this.encoding = "ascii";
		}

		public void SetSession(string key, string value, string path, string domain)
		{
			this.sessionKey = key;
			this.sessionValue = value;
			this.sessionPath = path;
			this.sessionDomain = domain;
		}

		public void SetMethod(string method)
		{
			if (method.ToUpper().Equals("POST"))
				this.method = "POST";
			else
				this.method = "GET";
		}

		public void AddFile(string name, string fileFullPath)
		{
			this.files.Add(new string[] { name, fileFullPath });
		}

		public void AddData(string name, string value)
		{
			this.datas.Add(new string[] { name, value });
		}

		public string Submit()
		{
			if (this.files.Count > 0 || this.method.Equals("POST"))
				return this.SubmitMethodPost();
			else
				return this.SubmitMethodGet();
		}

		private string SubmitMethodPost()
		{
			byte[] boundarybytes;

			// Create a boundry
			this.boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");

			// Create the web request
			this.httpWebRequest = (HttpWebRequest)WebRequest.Create(this.requestUrl);
			this.httpWebRequest.ContentType = "multipart/form-data; boundary=" + this.boundary;
			this.httpWebRequest.Method = "POST";
			this.httpWebRequest.KeepAlive = true;
			this.httpWebRequest.AllowWriteStreamBuffering = true;
			this.httpWebRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;

			// Cookies
			this.httpWebRequest.CookieContainer = new CookieContainer();
			if (this.sessionKey != null && this.sessionKey.Length > 0 && this.sessionValue != null && this.sessionValue.Length > 0)
			{
				this.httpWebRequest.CookieContainer.Add(new Cookie(this.sessionKey, this.sessionValue, this.sessionPath, this.sessionDomain));
			}

			this.httpWebRequest.ContentLength = 0;
			this.httpWebRequest.ContentLength += this.GetPostDataPacketLength();
			this.httpWebRequest.ContentLength += this.GetFilePacketLength();
			this.httpWebRequest.ContentLength += this.GetTrailingBoundary().Length;

			this.requestStream = this.httpWebRequest.GetRequestStream();

			// Write Post Data Packet
			this.StreamWritePostDataPacket();

			// Write files packet
			this.StreamWriteFilePacket();

			boundarybytes = Encoding.ASCII.GetBytes(this.GetTrailingBoundary());

			// Write out the trailing boundry
			this.requestStream.Write(boundarybytes, 0, boundarybytes.Length);

			// Close the request and file stream
			this.requestStream.Close();

			try
			{
				HttpWebResponse webResponse = (HttpWebResponse)this.httpWebRequest.GetResponse();
				this.responseStream = webResponse.GetResponseStream();
				this.responseReader = new StreamReader(responseStream);
				return responseReader.ReadToEnd();
			}
			catch (WebException e)
			{
				return e.Message;
			}
		}

		private string SubmitMethodGet()
		{
			string dataStr = "";
			foreach (string[] element in this.datas)
			{
				dataStr += element[0] + "=" + HttpUtility.UrlEncode(element[1]) + "&";
			}
			if (dataStr.Length > 0)
			dataStr = dataStr.Substring(0, dataStr.Length - 1);

			// Create the web request
			this.httpWebRequest = (HttpWebRequest)WebRequest.Create(this.requestUrl + "?" + dataStr);
			this.httpWebRequest.Method = "GET";
			this.httpWebRequest.KeepAlive = true;
			this.httpWebRequest.AllowWriteStreamBuffering = true;
			this.httpWebRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;

			// Cookies
			this.httpWebRequest.CookieContainer = new CookieContainer();
			if (this.sessionKey != null && this.sessionKey.Length > 0 && this.sessionValue != null && this.sessionValue.Length > 0)
			{
				this.httpWebRequest.CookieContainer.Add(new Cookie(this.sessionKey, this.sessionValue, this.sessionPath, this.sessionDomain));
			}

			try
			{
				HttpWebResponse webResponse = (HttpWebResponse)this.httpWebRequest.GetResponse();
				this.responseStream = webResponse.GetResponseStream();
				this.responseReader = new StreamReader(responseStream);
				return responseReader.ReadToEnd();
			}
			catch (WebException e)
			{
				return e.Message;
			}
		}

		private void StreamWritePostDataPacket()
		{
			byte[] bytes;
			foreach (string[] element in this.datas)
			{
				bytes = Encoding.ASCII.GetBytes(this.GetBoundary());
				this.requestStream.Write(bytes, 0, bytes.Length);
				bytes = this.EncodingGetBytes(string.Format(headerPostDataTemplate, element[0], element[1]));
				this.requestStream.Write(bytes, 0, bytes.Length);
			}
		}

		private void StreamWriteFilePacket()
		{
			byte[] bytes;
			foreach (string[] element in this.files)
			{
				bytes = Encoding.ASCII.GetBytes(this.GetBoundary());
				this.requestStream.Write(bytes, 0, bytes.Length);
				bytes = this.EncodingGetBytes(string.Format(headerFileTemplate, element[0], new FileInfo(element[1]).Name));
				this.requestStream.Write(bytes, 0, bytes.Length);

				// Open up a filestream.
				FileStream fileStream = new FileStream(element[1], FileMode.Open, FileAccess.Read);
				// Use 4096 for the buffer
				byte[] buffer = new byte[4096];
				int bytesRead = 0;
				// Loop through whole file uploading parts in a stream.
				while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
				{
					requestStream.Write(buffer, 0, bytesRead);
					requestStream.Flush();
				}
				fileStream.Close();
			}
		}

		private long GetPostDataPacketLength()
		{
			long length = 0;
			foreach (string[] element in this.datas)
			{
				length += Encoding.ASCII.GetBytes(this.GetBoundary()).Length;
				length += this.EncodingGetBytes(string.Format(headerPostDataTemplate, element[0], new FileInfo(element[1]).Name)).Length;
			}
			return length;
		}

		private long GetFilePacketLength()
		{
			long length = 0;
			foreach (string[] element in this.files)
			{
				length += Encoding.ASCII.GetBytes(this.GetBoundary()).Length;
				length += this.EncodingGetBytes(string.Format(headerFileTemplate, element[0], new FileInfo(element[1]).Name)).Length;
				length += new FileInfo(element[1]).Length;
			}
			return length;
		}

		private string GetBoundary()
		{
			return "\r\n--" + this.boundary + "\r\n";
		}

		private string GetTrailingBoundary()
		{
			return "\r\n--" + this.boundary + "--\r\n";
		}

		private byte[] EncodingGetBytes(string packet)
		{
			if (this.encoding.ToLower().Replace("-", "").Equals("utf7"))
			return System.Text.Encoding.UTF7.GetBytes(packet);
			else if (this.encoding.ToLower().Replace("-", "").Equals("utf8"))
			return System.Text.Encoding.UTF8.GetBytes(packet);
			else if (this.encoding.ToLower().Replace("-", "").Equals("utf32"))
			return System.Text.Encoding.UTF32.GetBytes(packet);
			else if (this.encoding.ToLower().Replace("-", "").Equals("unicode"))
			return System.Text.Encoding.Unicode.GetBytes(packet);
			else if (this.encoding.ToLower().Replace("-", "").Equals("bigendianunicode"))
			return System.Text.Encoding.BigEndianUnicode.GetBytes(packet);
			else if (this.encoding.ToLower().Replace("-", "").Equals("ascii"))
			return System.Text.Encoding.ASCII.GetBytes(packet);
			else
			return new byte[] { };
		}
	}
}

Leave a Reply

Your email address will not be published. Required fields are marked *