Saturday, 30 November 2013

How to use WebRequest to POST/Upload some data programmatically and read response using ASP.NET MVC?

In one of my project I got condition where I need to POST file along with data from my application to other application located on other server. I just want to POST some fields along with file same as we do with simple Form Submission but need to done it programmatically. So for this I used WebRequest Class in System.Net Namespace which makes a request to a Uniform Resource Identifier(URI).

I created following function which takes path of file to POST/Upload and URL to which make WebRequest.

public string PostData(string FilePath, string UrlToPost)
{
 string ResponseFromServer = string.Empty;

 try
 {
  /* Setting data fields to post */
  string DataToPost = "?username=myusername&password=mypassword&app=myapp";

  /* Generating Url to Request */
  Uri uri = new Uri(UrlToPost + DataToPost);

  string boundary = "----------" + System.DateTime.Now.Ticks.ToString("x");

  /* Creating WebRequest object and assigning Request Info. */
  HttpWebRequest MyRequest = (HttpWebRequest)WebRequest.Create(uri);
  MyRequest.ContentType = "multipart/form-data; boundary=" + boundary;
  MyRequest.Method = "POST";

  /* Build up the post message header */
  StringBuilder sb = new StringBuilder();
  sb.Append("--");
  sb.Append(boundary);
  sb.Append("\r\n");
  sb.Append("Content-Disposition: form-data; name=\"myfile\"; filename=\"");
  sb.Append(Path.GetFileName(FilePath));
  sb.Append("\"");
  sb.Append("\r\n");
  sb.Append("Content-Type: application/octect-stream \r\n");
  sb.Append("\r\n");

  string PostHeader = sb.ToString();
  byte[] PostHeaderBytes = Encoding.UTF8.GetBytes(PostHeader);

  /* Build the trailing boundary string as a byte array
     ensuring the boundary appears on a line by itself */
  byte[] BoundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");


  FileStream fileStream = new FileStream(Server.MapPath(FilePath), FileMode.Open, FileAccess.Read);
  long length = PostHeaderBytes.Length + fileStream.Length + BoundaryBytes.Length;
  MyRequest.ContentLength = length;

  Stream RequestStream = MyRequest.GetRequestStream();

  /* Write out our post header */
  RequestStream.Write(PostHeaderBytes, 0, PostHeaderBytes.Length);

  /* Write out the file contents */
  byte[] buffer = new Byte[checked((uint)Math.Min(4096, (int)fileStream.Length))];
  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 MyResponse = MyRequest.GetResponse();
  Stream s = MyResponse.GetResponseStream();
  StreamReader sr = new StreamReader(s);

  ResponseFromServer = sr.ReadToEnd();
 }
 catch (Exception ex)
 {

 }

 /* This is response from server to return */
 return ResponseFromServer;

}
When this function called all data fields along file posted to destination Url and we get posted data as it is posted by simple form submission but it's done programmatically.

I hope this article will help you. Please leave comments to improve this article, any suggestion also welcomed.

No comments:

Post a Comment