Tôi đã viết một lớp bằng cách sử dụng WebClient trở lại khi thực hiện tải lên biểu mẫu nhiều phần.
http://ferozedaud.blogspot.com/2010/03/multipart-form-upload-helper.html
/// 
/// MimePart
/// Abstract class for all MimeParts
/// 
abstract class MimePart
{
    public string Name { get; set; }
    public abstract string ContentDisposition { get; }
    public abstract string ContentType { get; }
    public abstract void CopyTo(Stream stream);
    public String Boundary
    {
        get;
        set;
    }
}
class NameValuePart : MimePart
{
    private NameValueCollection nameValues;
    public NameValuePart(NameValueCollection nameValues)
    {
        this.nameValues = nameValues;
    }
    public override void CopyTo(Stream stream)
    {
        string boundary = this.Boundary;
        StringBuilder sb = new StringBuilder();
        foreach (object element in this.nameValues.Keys)
        {
            sb.AppendFormat("--{0}", boundary);
            sb.Append("\r\n");
            sb.AppendFormat("Content-Disposition: form-data; name=\"{0}\";", element);
            sb.Append("\r\n");
            sb.Append("\r\n");
            sb.Append(this.nameValues[element.ToString()]);
            sb.Append("\r\n");
        }
        sb.AppendFormat("--{0}", boundary);
        sb.Append("\r\n");
        //Trace.WriteLine(sb.ToString());
        byte [] data = Encoding.ASCII.GetBytes(sb.ToString());
        stream.Write(data, 0, data.Length);
    }
    public override string ContentDisposition
    {
        get { return "form-data"; }
    }
    public override string ContentType
    {
        get { return String.Empty; }
    }
} 
class FilePart : MimePart
{
    private Stream input;
    private String contentType;
    public FilePart(Stream input, String name, String contentType)
    {
        this.input = input;
        this.contentType = contentType;
        this.Name = name;
    }
    public override void CopyTo(Stream stream)
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendFormat("Content-Disposition: {0}", this.ContentDisposition);
        if (this.Name != null)
            sb.Append("; ").AppendFormat("name=\"{0}\"", this.Name);
        if (this.FileName != null)
            sb.Append("; ").AppendFormat("filename=\"{0}\"", this.FileName);
        sb.Append("\r\n");
        sb.AppendFormat(this.ContentType);
        sb.Append("\r\n");
        sb.Append("\r\n");
    // serialize the header data.
    byte[] buffer = Encoding.ASCII.GetBytes(sb.ToString());
    stream.Write(buffer, 0, buffer.Length);
    // send the stream.
    byte[] readBuffer = new byte[1024];
    int read = input.Read(readBuffer, 0, readBuffer.Length);
    while (read > 0)
    {
        stream.Write(readBuffer, 0, read);
        read = input.Read(readBuffer, 0, readBuffer.Length);
    }
    // write the terminating boundary
    sb.Length = 0;
    sb.Append("\r\n");
    sb.AppendFormat("--{0}", this.Boundary);
    sb.Append("\r\n");
    buffer = Encoding.ASCII.GetBytes(sb.ToString());
    stream.Write(buffer, 0, buffer.Length);
}
 public override string ContentDisposition
 {
      get { return "file"; }
 }
 public override string ContentType
 {
    get { 
       return String.Format("content-type: {0}", this.contentType); 
     }
 }
 public String FileName { get; set; }
}
    /// 
    /// Helper class that encapsulates all file uploads
    /// in a mime part.
    /// 
    class FilesCollection : MimePart
    {
        private List files;
        public FilesCollection()
        {
            this.files = new List();
            this.Boundary = MultipartHelper.GetBoundary();
        }
        public int Count
        {
            get { return this.files.Count; }
        }
        public override string ContentDisposition
        {
            get
            {
                return String.Format("form-data; name=\"{0}\"", this.Name);
            }
        }
        public override string ContentType
        {
            get { return String.Format("multipart/mixed; boundary={0}", this.Boundary); }
        }
        public override void CopyTo(Stream stream)
        {
            // serialize the headers
            StringBuilder sb = new StringBuilder(128);
            sb.Append("Content-Disposition: ").Append(this.ContentDisposition).Append("\r\n");
            sb.Append("Content-Type: ").Append(this.ContentType).Append("\r\n");
            sb.Append("\r\n");
            sb.AppendFormat("--{0}", this.Boundary).Append("\r\n");
            byte[] headerBytes = Encoding.ASCII.GetBytes(sb.ToString());
            stream.Write(headerBytes, 0, headerBytes.Length);
            foreach (FilePart part in files)
            {
                part.Boundary = this.Boundary;
                part.CopyTo(stream);
            }
        }
        public void Add(FilePart part)
        {
            this.files.Add(part);
        }
    }
/// 
/// Helper class to aid in uploading multipart
/// entities to HTTP web endpoints.
/// 
class MultipartHelper
{
    private static Random random = new Random(Environment.TickCount);
    private List formData = new List();
    private FilesCollection files = null;
    private MemoryStream bufferStream = new MemoryStream();
    private string boundary;
    public String Boundary { get { return boundary; } }
    public static String GetBoundary()
    {
        return Environment.TickCount.ToString("X");
    }
    public MultipartHelper()
    {
        this.boundary = MultipartHelper.GetBoundary();
    }
    public void Add(NameValuePart part)
    {
        this.formData.Add(part);
        part.Boundary = boundary;
    }
    public void Add(FilePart part)
    {
        if (files == null)
        {
            files = new FilesCollection();
        }
        this.files.Add(part);
    }
    public void Upload(WebClient client, string address, string method)
    {
        // set header
        client.Headers.Add(HttpRequestHeader.ContentType, "multipart/form-data; boundary=" + this.boundary);
        Trace.WriteLine("Content-Type: multipart/form-data; boundary=" + this.boundary + "\r\n");
        // first, serialize the form data
        foreach (NameValuePart part in this.formData)
        {
            part.CopyTo(bufferStream);
        }
        // serialize the files.
        this.files.CopyTo(bufferStream);
        if (this.files.Count > 0)
        {
            // add the terminating boundary.
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("--{0}", this.Boundary).Append("\r\n");
            byte [] buffer = Encoding.ASCII.GetBytes(sb.ToString());
            bufferStream.Write(buffer, 0, buffer.Length);
        }
        bufferStream.Seek(0, SeekOrigin.Begin);
        Trace.WriteLine(Encoding.ASCII.GetString(bufferStream.ToArray()));
        byte [] response = client.UploadData(address, method, bufferStream.ToArray());
        Trace.WriteLine("----- RESPONSE ------");
        Trace.WriteLine(Encoding.ASCII.GetString(response));
    }
    /// 
    /// Helper class that encapsulates all file uploads
    /// in a mime part.
    /// 
    class FilesCollection : MimePart
    {
        private List files;
        public FilesCollection()
        {
            this.files = new List();
            this.Boundary = MultipartHelper.GetBoundary();
        }
        public int Count
        {
            get { return this.files.Count; }
        }
        public override string ContentDisposition
        {
            get
            {
                return String.Format("form-data; name=\"{0}\"", this.Name);
            }
        }
        public override string ContentType
        {
            get { return String.Format("multipart/mixed; boundary={0}", this.Boundary); }
        }
        public override void CopyTo(Stream stream)
        {
            // serialize the headers
            StringBuilder sb = new StringBuilder(128);
            sb.Append("Content-Disposition: ").Append(this.ContentDisposition).Append("\r\n");
            sb.Append("Content-Type: ").Append(this.ContentType).Append("\r\n");
            sb.Append("\r\n");
            sb.AppendFormat("--{0}", this.Boundary).Append("\r\n");
            byte[] headerBytes = Encoding.ASCII.GetBytes(sb.ToString());
            stream.Write(headerBytes, 0, headerBytes.Length);
            foreach (FilePart part in files)
            {
                part.Boundary = this.Boundary;
                part.CopyTo(stream);
            }
        }
        public void Add(FilePart part)
        {
            this.files.Add(part);
        }
    }
}
class Program
{
    static void Main(string[] args)
    {
        Trace.Listeners.Add(new ConsoleTraceListener());
        try
        {
            using (StreamWriter sw = new StreamWriter("testfile.txt", false))
            {
                sw.Write("Hello there!");
            }
            using (Stream iniStream = File.OpenRead(@"c:\platform.ini"))
            using (Stream fileStream = File.OpenRead("testfile.txt"))
            using (WebClient client = new WebClient())
            {
                MultipartHelper helper = new MultipartHelper();
                NameValueCollection props = new NameValueCollection();
                props.Add("fname", "john");
                props.Add("id", "acme");
                helper.Add(new NameValuePart(props));
                FilePart filepart = new FilePart(fileStream, "pics1", "text/plain");
                filepart.FileName = "1.jpg";
                helper.Add(filepart);
                FilePart ini = new FilePart(iniStream, "pics2", "text/plain");
                ini.FileName = "inifile.ini";
                helper.Add(ini);
                helper.Upload(client, "http://localhost/form.aspx", "POST");
            }
        }
        catch (Exception e)
        {
            Trace.WriteLine(e);
        }
    }
}
Điều này sẽ làm việc với tất cả các phiên bản của .NET framework.