Send binary data with HttpWebRequest - c#

I want to send some binary data from my WinForms c# application.
The server expects the data will be sent using POST request. I need to send several files and parameters, something like this:
file1=<binary data>
file2=<binary data>
desc1=<string>
desc2=<string>
I've searched that in Internet and MSDN and the code bellow is the most popular:
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("http://example.com");
webRequest.Method = "POST";
webRequest.ContentType = "multipart/form-data";
webRequest.ContentLength = data.Length;
using (Stream postStream = webRequest.GetRequestStream())
{
postStream.Write(data, 0, data.Length);
postStream.Close();
}
But I don't understand how to use this code to send several parameters? How can I set name for each of them?
Using GET I whould do &file=...&file2=...&desc1=...&desc2=... but using POST I have no clue what to do.

Related

php can't receive request from C# webrequest when post data length more than 8K

I am trying to send base64 encoded data through C# WebRequest to php script. Then I receive sent data by file_get_contents("php://input"), when data length is lower than 8 KBs the php code is executed, otherwise it can't be executed. In the other hand php didn't receive the request.
the code C#:
WebRequest request = WebRequest.Create(url);
request.Method = "POST";
// postData is Base64_encoded
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseData = reader.ReadToEnd();
responseData = SecurityUtils.DecryptUrlData(responseData);
reader.Close();
dataStream.Close();
response.Close();
return responseData;
Could any one help?
The below is incorrect (mea culpa). You cannot use enctype=multipart/form-data with php://input. See here
Perhaps you can post your PHP code into your question as well?
Make sure that when you POST from the c# app to your PHP app that you set the enctype to multipart/form-data.
Explanaition
Are you using application/x-www-form-urlencoded or multipart/form-data? There is a good explanation of the differenes here: application/x-www-form-urlencoded or multipart/form-data?
According to the link above, posting data in the application/x-form-urlencoded format will put the body into the URL. Many servers and languages (PHP, Apache) will cut off or throw errors when the URL is greater than 8K. See SO question: What is the maximum length for a URL?
Change the content type for the request
request.ContentType = "text/plain";
Check out php.iniĀ“s post_max_size on the server side

How we can Upload files into rackspace cloud container with API in C#

I want to Upload files into rackspace cloud container with API in C# and I am using .net 4.0 version. So, how I can create webrequest for this. Even I successfully created containers with the same request but I am not able to create object into my container.
Number of times I tried to upload my file into my container but I am continuously getting error like Unauthorized access and my code is shown below:
HttpWebRequest request = WebRequest.Create(new Uri(authInfo.StorageUrl + "/TestContainer/myfile.txt")) as HttpWebRequest;
request.Method = "PUT";
request.Headers["X-Auth-Token"] = MyToken;
byte[] data = System.IO.File.ReadAllBytes(#"D:\myfile.txt");
request.ContentLength = data.Length;
//request.Headers["Content-Length"] = "512000";
var response = request.GetResponse();
Please tell me what I am doing wrong with this.
You haven't written the bytes to the request stream. Do something like this:
Stream reqStream = request.GetRequestStream();
reqStream.Write(fileBytes, 0, fileBytes.Length);
reqStream.Close();
Webresponse response = request.getresponse();

C# Uploading file to HTTPServer

I need to write a httpclient to upload a huge file to the server using http. The code
public Stream function()
{
string postData = "This is a test that posts this string to a Web server.";
byte[] byteArray = Encoding.UTF8.GetBytes (postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
request.Method = "POST";
// Get the request stream.
Stream dataStream = request.GetRequestStream ();
// Write the data to the request stream.
return dataStream;
}
Then, I return the dataStream to the caller of this function so that the application keeps writing to the stream using write. Then once done with the writing, GetResponse is called and then the stream is closed. But I get the exception
ProtocolViolationException
at System.Net.HttpWriteStream.Write() while writing to the stream.
Kindly help.
Have you considered using Fiddler to debug the process when using a browser? This is a simple proxy allowing you to inspect http traffic.
The ProtocolViolationException is probably thrown because the request method is GET or HEAD.
You must set the Method to POST like this:
// Set the 'Method' property of the 'Webrequest' to 'POST'.
request.Method = "POST";
See HttpWebRequest.GetRequestStream Method documentation on MSDN.

C# HttpWebRequest with XML Structured Data

I'm developing the client-side of a third party webservice. The purpose is that I send xml-file to the server.
How should I attach the xml-file to the httpwebrequest? What contentType is needed? More suggestions?
I cannot use mtom or dime.ie because I am using httpwebrequest. I am unable to use WCF either.
Here is a very basic method of sending XML structured data using HttpWebRequest (by the way you need to use request.ContentType = "application/xml";) :
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(myUrl));
request.Method = "POST";
request.ContentType = "application/xml";
request.Accept = "application/xml";
XElement redmineRequestXML =
new XElement("issue",
new XElement("project_id", 17)
);
byte[] bytes = Encoding.UTF8.GetBytes(redmineRequestXML.ToString());
request.ContentLength = bytes.Length;
using (Stream putStream = request.GetRequestStream())
{
putStream.Write(bytes, 0, bytes.Length);
}
// Log the response from Redmine RESTful service
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
Logger.Info("Response from Redmine Issue Tracker: " + reader.ReadToEnd());
}
I use this at one of my projects (NBug) to submit an issue report to my Redmine issue tracker which accepts XML structured data over web requests (via POST). If you need further examples, you can get a couple of fully featured examples here: http://nbug.codeplex.com/SourceControl/list/changesets (click 'Browse' under 'Latest Verion' label on the right then navigate to "NBug\Submit\Tracker\Redmine.cs")

Anyone have sample code for doing a "chunked" HTTP streaming download of one web directly to a upload to a separate web server?

Background - I'm trying to stream an existing webpage to a separate web application, using HttpWebRequest/HttpWebResponse in C#. One issue I'm striking is that I'm trying to set the file upload request content-length using the file download's content-length, HOWEVER the issue seems to be when the source webpage is on a webserver for which the HttpWebResponse doesn't provide a content length.
HttpWebRequest downloadRequest = WebRequest.Create(new Uri("downloaduri")) as HttpWebRequest;
using (HttpWebResponse downloadResponse = downloadRequest.GetResponse() as HttpWebResponse)
{
var uploadRequest = (HttpWebRequest) WebRequest.Create(new Uri("uripath"));
uploadRequest.Method = "POST";
uploadRequest.ContentLength = downloadResponse.ContentLength; // ####
QUESTION : How could I update this approach to cater for this case (when the download response doesn't have a content-length set). Would it be to somehow use a MemoryStream perhaps? Any sample code would be appreciated. In particular is there a code sample someone would have that shows how to do a "chunked" HTTP download & upload to avoid any issues of the source web server not providing content-length?
Thanks
As I already applied in the Microsoft Forums, there are a couple of options that you have.
However, this is how I would do it with a MemoryStream:
HttpWebRequest downloadRequest = WebRequest.Create(new Uri("downloaduri")) as HttpWebRequest;
byte [] buffer = new byte[4096];
using (MemoryStream ms = new MemoryStream())
using (HttpWebResponse downloadResponse = downloadRequest.GetResponse() as HttpWebResponse)
{
Stream respStream = downloadResponse.GetResponseStream();
int read = respStream.Read(buffer, 0, buffer.Length);
while(read > 0)
{
ms.Write(buffer, 0, read);
read = respStream.Read(buffer, 0, buffer.Length);
}
// get the data of the stream
byte [] uploadData = ms.ToArray();
var uploadRequest = (HttpWebRequest) WebRequest.Create(new Uri("uripath"));
uploadRequest.Method = "POST";
uploadRequest.ContentLength = uploadData.Length;
// you know what to do after this....
}
Also, note that you really don't need to worry about knowing the value for ContentLength a priori. As you have guessed, you could have set SendChunked to true on uploadRequest, and then just copied from the download stream into the upload stream. Or, you can just do the copy without setting chunked, and HttpWebRequest (as far as I know) will buffer the data internally (make sure AllowWriteStreamBuffering is set to true on uploadrequest) and figure out the content length and send the request.

Categories