Tuesday, December 24, 2013

Upload Multiple Files through HTTP MultiPart Request(.NET to Java Servelet)


Multiple Files Directory Upload from .NET(.ASPX)  through HTTP Multipart Request:
 


Friends after huge R & D I have solved the problem where I have to upload multiple files from multiple folders to Gateway(where Java Application runs) through strict http multi-part request.


This Code below is implemented & tested, works fine for uploading multiple files in each folder,

I am showing the file screen shot which I have to upload with this code:


Screen1:shows  all folders location whose files I need to upload

Screen2: shows the files inside each folder which have to be upload
Note: this  code also works for uploading from aspx(.net) other platform applications with http Url,ex:java,php,even..etc you can do upload to same platform .net

With slight modifications to the code you can do upload in a way you want,Now Let us start with step by step

Step1: Actual function which will be called with all files to upload
public static HttpWebResponse Upload(HttpWebRequest req, UploadFile[] files, NameValueCollection form)
{
List<MimePart> mimeParts = new List<MimePart>();
try
{
foreach (string key in form.AllKeys)
{
StringMimePart part = new StringMimePart();
part.Headers["Content-Disposition"] = "form-data; name=\"" + key + "\"";
part.StringData = form[key];
mimeParts.Add(part);
}
int nameIndex = 0;
foreach (UploadFile file in files)
{
StreamMimePart part = new StreamMimePart();
if (string.IsNullOrEmpty(file.FieldName))
file.FieldName = "file" + nameIndex++;
part.Headers["Content-Disposition"] = "form-data; name=\"" + file.FieldName + "\"; filename=\"" + file.FileName + "\"";
part.Headers["Content-Type"] = file.ContentType;
part.SetStream(file.Data);
mimeParts.Add(part);
}
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
req.ContentType = "multipart/form-data; boundary=" + boundary;
req.Method = "POST";
long contentLength = 0;
byte[] _footer = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");
foreach (MimePart part in mimeParts)
{
contentLength += part.GenerateHeaderFooterData(boundary);
}
req.ContentLength = contentLength + _footer.Length;
byte[] buffer = new byte[8192];
byte[] afterFile = Encoding.UTF8.GetBytes("\r\n");
int read;
using (Stream s = req.GetRequestStream())
{
foreach (MimePart part in mimeParts)
{
s.Write(part.Header, 0, part.Header.Length);
while ((read = part.Data.Read(buffer, 0, buffer.Length)) > 0)
s.Write(buffer, 0, read);
part.Data.Dispose();
s.Write(afterFile, 0, afterFile.Length);
}
s.Write(_footer, 0, _footer.Length);
}
return (HttpWebResponse)req.GetResponse();
}
catch
{
foreach (MimePart part in mimeParts)
if (part.Data != null)
part.Data.Dispose();
throw;
}
}


 Step2: Add Class StringMimePart.cs Used by Upload function in Step1
 
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace UploadHelper
{
public class StringMimePart : MimePart
{
Stream _data;
public string StringData
{
set
{
_data = new MemoryStream(Encoding.UTF8.GetBytes(value));
}
}
public override Stream Data
{
get
{
return _data;
}
}
}
}
Step3: Add Class UploadFile.cs Used by Upload function in Step1 
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace UploadHelper
{
public class UploadFile
{
Stream _data;
string _fieldName;
string _fileName;
string _contentType;
public UploadFile(Stream data, string fieldName, string fileName, string contentType)
{
_data = data;
_fieldName = fieldName;
_fileName = fileName;
_contentType = contentType;
}
public UploadFile(string fileName, string fieldName, string contentType)
: this(File.OpenRead(fileName), fieldName, Path.GetFileName(fileName), contentType)
{ }
public UploadFile(string fileName)
: this(fileName, null, "application/octet-stream")
{ }
public Stream Data
{
get { return _data; }
set { _data = value; }
}
public string FieldName
{
get { return _fieldName; }
set { _fieldName = value; }
}
public string FileName
{
get { return _fileName; }
set { _fileName = value; }
}
public string ContentType
{
get { return _contentType; }
set { _contentType = value; }
}
}
}
Step4: Add Class HttpUploadHelper.cs Used by Upload function in Step1
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;
using System.Net;
using System.IO;
namespace UploadHelper
{
public class HttpUploadHelper
{
private HttpUploadHelper()
{ }
public static string Upload(string url, UploadFile[] files, NameValueCollection form)
{
HttpWebResponse resp = Upload((HttpWebRequest)WebRequest.Create(url), files, form);
using (Stream s = resp.GetResponseStream())
using (StreamReader sr = new StreamReader(s))
{
return sr.ReadToEnd();
}
}
public static HttpWebResponse Upload(HttpWebRequest req, UploadFile[] files, NameValueCollection form)
{
List<MimePart> mimeParts = new List<MimePart>();
try
{
foreach (string key in form.AllKeys)
{
StringMimePart part = new StringMimePart();
part.Headers["Content-Disposition"] = "form-data; name=\"" + key + "\"";
part.StringData = form[key];
mimeParts.Add(part);
}
int nameIndex = 0;
foreach (UploadFile file in files)
{
StreamMimePart part = new StreamMimePart();
if (string.IsNullOrEmpty(file.FieldName))
file.FieldName = "file" + nameIndex++;
part.Headers["Content-Disposition"] = "form-data; name=\"" + file.FieldName + "\"; filename=\"" + file.FileName + "\"";
part.Headers["Content-Type"] = file.ContentType;
part.SetStream(file.Data);
mimeParts.Add(part);
}
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
req.ContentType = "multipart/form-data; boundary=" + boundary;
req.Method = "POST";
long contentLength = 0;
byte[] _footer = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");
foreach (MimePart part in mimeParts)
{
contentLength += part.GenerateHeaderFooterData(boundary);
}
req.ContentLength = contentLength + _footer.Length;
byte[] buffer = new byte[8192];
byte[] afterFile = Encoding.UTF8.GetBytes("\r\n");
int read;
using (Stream s = req.GetRequestStream())
{
foreach (MimePart part in mimeParts)
{
s.Write(part.Header, 0, part.Header.Length);
while ((read = part.Data.Read(buffer, 0, buffer.Length)) > 0)
s.Write(buffer, 0, read);
part.Data.Dispose();
s.Write(afterFile, 0, afterFile.Length);
}
s.Write(_footer, 0, _footer.Length);
}
return (HttpWebResponse)req.GetResponse();
}
catch
{
foreach (MimePart part in mimeParts)
if (part.Data != null)
part.Data.Dispose();
throw;
}
}
}
}

Step5: How am I calling the function to Upload 

int status = 0;
string source = "Give your Source Path to Upload"
string posturl="Give Your Servelet Url or Any other Url to Upload Multiple FIles"
string[] enrolldirect;
int FindDirectoriesLength=System.IO.Directory.GetDirectories(source).Length ;
string SuccessUploadedFiles = ConfigurationManager.AppSettings.Get("UploadedEnrollmentsSource");//Back Up Path from web.config
if (FindDirectoriesLength == 0)
{
status = 0;
}
else
{
enrolldirect = Directory.GetDirectories(source).ToArray();
//Note: For Https Url  Upload we should include this line for certification
//ServicePointManager.ServerCertificateValidationCallback = new
System.Net.Security.RemoteCertificateValidationCallback(delegate { return true; });
//For Http Url no need to include above

HttpWebRequest webreq = (HttpWebRequest)WebRequest.Create(posturl);
NameValueCollection nvc = new NameValueCollection();
nvc.Add("namevaluecollection1", "123456"); //optional include as per your req.
nvc.Add("namevaluecollection2", "32145");//optional include as per your req.
nvc.Add("namevaluecollection3", "2356");//optional include as per your req.

foreach (string dir in enrolldirect)
{
if (VerifyFiles(dir))
{
string[] enrollfiles = Directory.GetFiles(dir).ToArray();
UploadFile[] files = new UploadFile[enrollfiles.Length];
for (int i = 0; i < enrollfiles.Length; i++)
{
files[i] = new UploadFile(enrollfiles[i]);
}
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(posturl);
HttpWebResponse resp = HttpUploadHelper.Upload(req, files, nvc);
StreamReader respreader = new StreamReader(resp.GetResponseStream());
string response = respreader.ReadToEnd();//Read the Response and do your stuff if needed
if (response.Trim() != "")
{
 //Update db,noting log..etc
}
}

No comments: