Introduction
Here we will describe a simple procedure to make a request of type "multipart/form-data" from C# using the HttpWebRequest class. Taking as refence the article published in the web : Browsing_the_WEB_with_C_.asp .
Content
The big problem of this type of request is how to prepare the data package that will be passed to the class. For this, the more easy way to do this is making a string with the data in text form. You will must be careful with this, because if you put wrong a character or separator the package wont get to destiny successfully.
The next method make this action about a parameters collection, these parameters can be different type, because by this way you will can sending the file content.
"cs">private string GetPostData()
{
string boundary = "--" + this._Boundary;
int arrReqs = this._ParamsCollection.Count * 5;
string[] auxReqBody = new string[arrReqs];
int count = 0;
foreach(ParamsStruct par in this._ParamsCollection)
{
auxReqBody[count] = boundary;
count++;
switch (par.Type)
{
case ParamsStruct.ParamType.File:
{
auxReqBody[count] = "Content-Disposition: file; name=\"" + par.Name + "\"; filename=\"" + par.GetOnlyFileName() + "\"";
count++;
auxReqBody[count] = "Content-Type: text/plain";
count++;
auxReqBody[count] = "";
count++;
auxReqBody[count] = par.StringValue;
count++;
break;
}
case ParamsStruct.ParamType.Parameter:
default:
{
auxReqBody[count] = "Content-Disposition: form-data; name=\"" + par.Name + "\"";
count++;
auxReqBody[count] = "";
count++;
auxReqBody[count] = par.StringValue;
count++;
break;
}
}
}
auxReqBody[count] = boundary;
count++;
string requestBody = String.Join("\r\n",auxReqBody);
return requestBody;
}
Then if we inform in the parameters collection : one parameter of type "Parameter", name "param1" and value "param1Value" and one parameter of type "File", name "file", file name "fileName1.txt" and value "Content of fileName1.txt", after run of this method you will obtain a text with this format:
--AaB03x\r\n Content-Disposition: form-data; name="param1"\r\n \r\n param1Value\r\n --AaB03x\r\n Content-Disposition: file; name="file"; filename="fileName1.txt"\r\n Content-Type: text/plain\r\n \r\n Content of fileName1.txt \r\n --AaB03x\r\n
|
After this, we will use a method similar to this one, for sending the information to the required page.
"cs">public void PostData ()
{
Uri urlUri = new Uri(_URL);
ASCIIEncoding encoding = new ASCIIEncoding();
string postData = this.GetPostData();
byte[] buffer = encoding.GetBytes( postData );
HttpWebRequest myRequest =(HttpWebRequest)WebRequest.Create(urlUri);
myRequest.Method = this._Method;
myRequest.AllowWriteStreamBuffering = true;
string auxContent = this._ContentType;
if (this._Boundary.Length > 0)
auxContent += "boundary=" + this._Boundary;
myRequest.ContentType = auxContent;
myRequest.Accept = this._Accept;
myRequest.ContentLength = buffer.Length;
Stream newStream = myRequest.GetRequestStream();
newStream.Write(buffer,0,buffer.Length);
newStream.Close();
_myHttpWebResponse= (HttpWebResponse)myRequest.GetResponse();
this._ResponseStream = _myHttpWebResponse.GetResponseStream();
}
For finishing this, we must process the request stream returned by the required page. In this case I declare one property inside class that transform the response stream to string.
"cs">public string ResponseString
{
get
{
string resultData = "";
StreamReader streamRead = new StreamReader( _ResponseStream );
Char[] readBuffer = new Char[256];
int count = streamRead.Read( readBuffer, 0, 256 );
while (count > 0)
{
resultData += new String( readBuffer, 0, count);
Console.WriteLine( resultData );
count = streamRead.Read( readBuffer, 0, 256);
}
streamRead.Close();
return resultData;
}
}
In simple way, this will adapt to another content type. Remember that the key is the form for load the data package.
For SSL page type see request_SSL_from_C_.asp