First of all, I am using Visual Studio 2005 to write my program. I am using C# .NET as the language. I am running Windows XP Professional with all service packs and updates applied.
Now, I have been trying to write a program that batch uploads pictures to the image hosting service ImageVenue, http://www.imagevenue.com (On a side note, I have tried also with ImageShack but also had the same results). I can't seem to get it right because ImageVenue never returns the linking code to the image. I will post my code as well as some other stuff I have grabbed along the way in hopes that somebody can pick out my error. The code I have written has mostly been borrowed from the web but I have also added to it. I am using a class called MultipartFileUpload to do the uploading and I have written a sort of "driver" program to test the class. I will post the MultipartFileUpload code first.
Here is the code for MultipartFileUpload:
Expand|Select|Wrap|Line Numbers
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Collections.Specialized;
- using System.Net;
- using System.IO;
- namespace IVUp
- {
- public class MultipartFileUpload
- {
- private Uri uri = null;
- private NameValueCollection parameters = null;
- private NameValueCollection formData = null;
- private String fileDisplayName = null;
- private String fileParameterName = null;
- private FileInfo file = null;
- private NetworkCredential networkCredential = null;
- private String boundary = null;
- private readonly int BUFFER_SIZE = 500;
- #region constructors
- public MultipartFileUpload()
- {
- parameters = new NameValueCollection();
- formData = new NameValueCollection();
- //the boundary signals the we server to look for a new form value or data segment
- boundary = "----------" + DateTime.Now.Ticks.ToString("x");
- }
- public MultipartFileUpload(Uri uri) : this()
- {
- this.uri = uri;
- }
- #endregion
- #region getters and setters
- /// <summary>
- /// the destination of the multipart file upload
- /// </summary>
- public Uri Uri
- {
- get { return this.uri; }
- set { this.uri = value; }
- }
- /// <summary>
- /// the parameters to be passed along with the post method — optional
- /// </summary>
- public NameValueCollection Parameters
- {
- get { return this.parameters; }
- set { this.parameters = value; }
- }
- /// <summary>
- /// any form data associated with the post method
- /// </summary>
- public NameValueCollection FormData
- {
- get { return this.formData; }
- set { this.formData = value; }
- }
- /// <summary>
- /// if your web server requires credentials to upload a file, set them here — optional
- /// </summary>
- public NetworkCredential NetworkCredential
- {
- get { return this.networkCredential; }
- set { this.networkCredential = value; }
- }
- #endregion
- #region public methods
- /// <summary>
- /// adds a parameter to the request, if the parameter already has a value,
- /// it will be overwritten
- /// </summary>
- /// <param name="name">name of the parameter</param>
- /// <param name="value">value of the parameter</param>
- public void AddParameter(String name, String value)
- {
- if (this.parameters == null)
- {
- this.parameters = new NameValueCollection();
- }
- this.parameters.Set(name, value);
- }
- /// <summary>
- /// adds a form value to the request, if the form field already exists, overwrite it
- /// </summary>
- /// <param name="name">the name of the form field</param>
- /// <param name="value">value of the form field</param>
- public void AddFormValue(String name, String value)
- {
- if (this.formData == null)
- {
- this.formData = new NameValueCollection();
- }
- this.parameters.Set(name, value);
- }
- /// <summary>
- /// attach a file to the post method, the parameter name and file can not be null
- /// </summary>
- /// <param name="fileDisplayName">the name of the file as it should appear to the web server</param>
- /// <param name="parameterName">the parameter that your web server expects to be associated with a file</param>
- /// <param name="file">the actual file you want to upload</param>
- /// <exception cref="ArgumentNullException">file can not be null, name of the parameter can’t be null</exception>
- public void AttachFile(String fileDisplayName, String parameterName, FileInfo file)
- {
- if(file == null)
- {
- throw new ArgumentNullException("file", "You must pass a reference to a file");
- }
- if (parameterName == null)
- {
- throw new ArgumentNullException("parameterName", "You must provide the name of the file parameter.");
- }
- this.file = file;
- if (this.fileDisplayName == null)
- {
- this.fileDisplayName = file.Name;
- }
- }
- /// <summary>
- /// performs the actual upload
- /// </summary>
- /// <returns>the response as a string</returns>
- public String UploadFileEx()
- {
- //tack on any parameters or just give us back the uri if there are no parameters
- Uri targetUri = CreateUriWithParameters();
- HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(targetUri);
- webrequest.Credentials = networkCredential; //fine if it’s null
- webrequest.ContentType = "multipart/form-data; boundary=" + boundary;
- webrequest.Method = "POST";
- //encode header
- String postHeader = CreatePostDataString();
- byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);
- byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n–" + boundary + "\r\n");
- //read in the file as a stream
- FileStream fileStream = file.Open(FileMode.Open, FileAccess.Read);
- long length = postHeaderBytes.Length + fileStream.Length +boundaryBytes.Length;
- //the request method needs to know how big the file is before we start the upload
- webrequest.ContentLength = length;
- Stream requestStream = webrequest.GetRequestStream();
- // Write out our post header
- requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
- // Write out the file contents
- byte[] buffer = new byte[BUFFER_SIZE];
- int bytesRead = 0;
- while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
- {
- requestStream.Write(buffer, 0, bytesRead);
- }
- // Write out the trailing boundary
- requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
- WebResponse response = webrequest.GetResponse();
- StreamReader sr = new StreamReader(response.GetResponseStream());
- return sr.ReadToEnd(); //response body
- }
- #endregion
- #region private methods
- /// <summary>
- /// helper method to tack on parameters to the request
- /// </summary>
- /// <returns>Uri with parameters, or the original uri if it’s null</returns>
- private Uri CreateUriWithParameters()
- {
- if (uri == null) return null;
- if (parameters == null || parameters.Count <= 0)
- {
- return this.uri;
- }
- String paramString = "?";
- foreach (String key in parameters.Keys)
- {
- paramString += key + "=" + parameters.Get(key)+"&";
- }
- paramString = paramString.Substring(0, paramString.Length - 1); //strip off last &
- return new Uri(uri.ToString() + paramString);
- }
- /// <summary>
- /// post data as a string with the boundaries
- /// </summary>
- /// <returns>a string representing the form data</returns>
- private String CreatePostDataString()
- {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < formData.Count; i++)
- {
- sb.Append("–" + boundary + "\r\n");
- sb.Append("Content-Disposition: form-data; name=\"");
- sb.Append(formData.GetKey(i) + "\"\r\n\r\n" + formData.Get(i) + "\r\n");
- }
- sb.Append("–" + boundary + "\r\n");
- sb.Append("Content-Disposition: form-data; name=\"" + fileParameterName + "\";");
- sb.Append("filename=\"" + fileDisplayName + "\" Content-Type: application/octet-stream\r\n\r\n");
- return sb.ToString();
- }
- #endregion
- }
- }
Expand|Select|Wrap|Line Numbers
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Text;
- using System.Windows.Forms;
- using System.IO;
- namespace IVUp
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
- private void button1_Click(object sender, EventArgs e)
- {
- //MultipartFileUpload Class Code
- String UploadResults = "";
- MultipartFileUpload MyMultipart = new MultipartFileUpload();
- Uri MyUri = new Uri("http://imagevenue.com/upload.php");
- MyMultipart.Uri = MyUri;
- openFileDialog1.ShowDialog();
- FileInfo MyFile = new FileInfo(openFileDialog1.FileName);
- //MyMultipart.AddFormValue("hostval", "10");
- MyMultipart.AttachFile("Test.jpg", "userfile[]", MyFile);
- //MyMultipart.AddFormValue("userfile[]", "C:\\Test.jpg");
- MyMultipart.AddFormValue("imgcontent", "notsafe");
- MyMultipart.AddFormValue("MAX_FILE_SIZE", "");
- MyMultipart.AddFormValue("action", "1");
- MyMultipart.AddFormValue("img_resize", "");
- UploadResults = MyMultipart.UploadFileEx();
- richTextBox1.Text = UploadResults;
- }
- }
- }
POST /upload.php HTTP/1.1
Host: imagevenue.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.5) Gecko/20070713 ImageShackToolbar/4.2.1 Firefox/2.0.0.5
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://imagevenue.com/host.php
Cookie: __utmz=122915731.1183006481.1.1.utmccn=(direct)|ut mcsr=(direct)|utmcmd=(none); pval=1185169867; __utma=122915731.858623389.1183006481.1183006481.1 186080644.2; __utmc=122915731
And here is what the stuff from my program has looked like so far:
POST /upload.php?imgcontent=notsafe&MAX_FILE_SIZE=&actio n=1&img_resize= HTTP/1.1
Content-Type: multipart/form-data; boundary=----------8c9a331c0cc2e10
Host: imagevenue.com
Content-Length: 12888
Expect: 100-continue
Connection: Keep-Alive
Any help on this would be greatly appreciated. Thanks.