Complete Web Fields via HttpWebRequest Boundary – C#

c# http web requests

In this tutorial I will show you how to complete some fields on a web page when POST date are sent via Content-Disposition: form-data; , in other words via Boundary, into your C# Application. The example can be easily adapted on any .NET Language and in other Programming Languages because is the same principle.

 

I will not explain how HTTP Requests and HTTP Response works (maybe into another post), I will show exactly  how to Complete fields on webpages via Boundary.

Before begin, you should know that this king of request looks like:

Post data:

—————————–18132228322538\r\n
Content-Disposition: form-data; name=”user”\r\n
\r\n
username\r\n
—————————–18132228322538\r\n
Content-Disposition: form-data; name=”password”\r\n
\r\n
password\r\n
—————————–18132228322538\r\n
Content-Disposition: form-data; name=”submit”\r\n
\r\n
Login\r\n
—————————–18132228322538–\r\n

And headers will contain this:

…………………………………….headers content…………………………….
Content-Type: multipart/form-data; boundary=—————————18132228322538
Content-Length: 123

 

So, there is a login form with two fields and one submit button which will look like:

login_fields

Via HttpWebRequests we will complete these two fields and press Login button pragmatically without using a WebBrowser.

Step1:

Add this class to your project as PostData.cs :

(Solution Explorer >> Right on your project name >> Add >> Class…)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyNamespace
{
    public class PostData
    {
        public static string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
        private List m_Params;

        public List Params
        {
            get { return m_Params; }
            set { m_Params = value; }
        }

        public PostData()
        {
            m_Params = new List();
        }

        public string GetPostData()
        {
            StringBuilder sb = new StringBuilder();
            foreach (PostDataParam p in m_Params)
            {
                sb.AppendLine("--" + boundary);
                if (p.Type == PostDataParamType.File)
                {
                    sb.AppendLine(string.Format("Content-Disposition: file; name=\"{0}\"; filename=\"{1}\"", p.Name, p.FileName));
                    sb.AppendLine("Content-Type: application/octet-stream");
                    sb.AppendLine();
                    sb.AppendLine(p.Value);
                }
                else
                {
                    sb.AppendLine(string.Format("Content-Disposition: form-data; name=\"{0}\"\r\n", p.Name));
                    sb.AppendLine(p.Value);
                }
            }
            sb.AppendLine("--" +boundary + "--");
            return sb.ToString();
        }
    }

    public enum PostDataParamType
    {
        Field,
        File
    }

    public class PostDataParam
    {
        public PostDataParam(string name, string value, PostDataParamType type)
        {
            Name = name;
            Value = value;
            Type = type;
        }

        public PostDataParam(string name, string filename, string value, PostDataParamType type)
        {
            Name = name;
            Value = value;
            FileName = filename;
            Type = type;
        }

        public string Name;
        public string FileName;
        public string Value;
        public PostDataParamType Type;
    }
}

Ok, now assuming that you’ve added this class to your project let’s go to next step.

Step2:

Now we have to use this class in our program. In our HttpWebRequest we will complete User and Password field and will press login Button:

private void loginButton_Click(object sender, EventArgs e)
{
    try
    {
        HttpWebRequest oRequest = null;
        oRequest = (HttpWebRequest)HttpWebRequest.Create(loginLinkPost);
        oRequest.ContentType = "multipart/form-data; boundary=" + PostData.boundary;
        oRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0";

        oRequest.KeepAlive = true;
        oRequest.AllowAutoRedirect = true;

        oRequest.Method = "POST";
        oRequest.CookieContainer = new CookieContainer() //create a global variable if you want to keep cookies for future requests
        PostData pData = new PostData();
        Encoding encoding = Encoding.UTF8;
        System.IO.Stream oStream = null;
        pData.Params.Add(new PostDataParam("user", "yourUsernameHHere", PostDataParamType.Field));
        pData.Params.Add(new PostDataParam("password", this.passwordBox.Text, PostDataParamType.Field));
        pData.Params.Add(new PostDataParam("Submit", "Login", PostDataParamType.Field));

        byte[] buffer = encoding.GetBytes(pData.GetPostData());

        oRequest.ContentLength = buffer.Length;
        oStream = oRequest.GetRequestStream();
        oStream.Write(buffer, 0, buffer.Length);
        oStream.Close();

        string source = "";
        using (HttpWebResponse oResponse = (HttpWebResponse)oRequest.GetResponse())
        {
            if (oResponse.StatusCode == HttpStatusCode.OK)
            {
                System.IO.Stream responseStream = oResponse.GetResponseStream();
                System.IO.StreamReader reader = new System.IO.StreamReader(responseStream, Encoding.UTF8);
                source = reader.ReadToEnd();

                if(source.Contans("Something after log in....")
                    MessageBox.Show("Logged in :)!");
                else
                    MessageBox.Show("Failed to log in...");
            }
            else
                MessageBox.Show("Server failed to respond!", "Error!");

        }
    }

    catch(Exception ex)
    {
        MessageBox.Show(ex.ToString(), "Error when try to login...");
    }
}

You can add as many fields you want by adding this line:

pData.Params.Add(new PostDataParam("FieldName", "valueWhichYouWantToInsertIntoField", PostDataParamType.Field));

So, I think that’s all!

Conclusion

You know now how to complete fields programmatically on a web page and submit request via boundary.

PS: Using that class (PostData.cs) you can upload files too using this line in webRequest:

pData.Params.Add(new PostDataParam("FieldName", "filename", "value", PostDataParamType.<strong>File</strong>));

but I did not tested It so I can’t told you exactly how it works.  You can leave as comment a website which is getting uploaded files via Boundary and I will test it and add to post.

PS2: You can use Fiddler to see how your http requests are outgoing and if look like requests before step 1. Every space and newline is critical, so be careful.
Sources: Google and http://stackoverflow.com/questions/219827/multipart-forms-from-c-sharp-client

Please comment If something is unclear.

Related posts:

Got something to say? Go for it!