Thursday, October 18, 2012

How to upload file using Resty.Net?

The bad news

Most of the REST clients comes with a built in mechanism to upload files. I also have plans to add such a feature in Resty.Net very soon, but as of now it doesn't have easy way to upload files.

The good news

If you are following Resty.Net for sometime then you may know that the goal of Resty.Net is to provide a powerful low level api making it just a thin layer above the HttpWebRequest class provided by dotnet, while also giving the highlevel goodness similar to other existing REST client libraries.

Due to its bare to the metal, low level nature, it is already possible to write codes to upload file using those low level features of Resty.Net. Most of the time if anything can be done through HttpWebRequest class, then it may also be possible to do same using Resty.Net. Here is an example of how you'd do it using the HttpWebRequest class http://www.dotnetthoughts.net/how-to-upload-file-using-httpwebrequest-class/

Ok, I got how to do it with HttpWebRequest. Show me how to do it with Resty.Net

Here is how:


string boundary = Guid.NewGuid().ToString();
RestRequest request = new RestRequest(HttpMethod.POST, new RestUri(_MyUri, "/File"));
request.ContentType = ContentType.MultiPartFormData.WithBoundary(boundary);

string[] files = new string[] 
{ 
"example1.jpg",
"example2.png"
};

IDictionary<string, string> formData = new Dictionary<string, string>
{
 {"Name", "nrip"},
 {"EmailAddress", "nrip@abc.com"},
};

StringBuilder sb = new StringBuilder();

foreach (var file in files)
{
 sb.AppendFormat("--{0}", boundary);
 sb.AppendFormat("\r\n");
 sb.AppendFormat("Content-Disposition: form-data; name=\"media\"; filename=\"" + Path.GetFileName(file) + "\"");
 sb.AppendFormat("\r\n");
 sb.AppendFormat("Content-Type:  " + MimeTypes.GetMimeType(Path.GetExtension(file)) ?? ContentType.ApplicationOctetStream.ToString());
 sb.AppendFormat("\r\n");
 sb.AppendFormat("\r\n");
 using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
 {
  byte[] contents = new byte[fs.Length];
  fs.Read(contents, 0, contents.Length);
  sb.Append(Encoding.Default.GetString(contents));
 }
 sb.AppendFormat("\r\n");
}

foreach (var keyvaluepair in formData)
{
 sb.AppendFormat("--{0}", boundary);
 sb.AppendFormat("\r\n");
 sb.AppendFormat("Content-Disposition: form-data; name=\"" + keyvaluepair.Key + "\"");
 sb.AppendFormat("\r\n");
 sb.AppendFormat("\r\n");
 sb.AppendFormat(keyvaluepair.Value);
 sb.AppendFormat("\r\n");
}

sb.AppendFormat("--{0}--", boundary);
byte[] fulldata = Encoding.Default.GetBytes(sb.ToString());

var body = new RestRawRequestBody(fulldata);
request.Body = body;

//Actual posting of body content will occure herer
var response = request.GetResponse();

Most of the part would be very comparable to the original post, constructing the multi-part form data structure. Resty.Net has a Body type called RestRawRequestBody, which takes raw byte array (byte[]) as the body content. Body content are sent to the server, obviously putting them in the Request body. I'll discuss more on other RestBodies available in Resty.Net in future. For now I think the above capability of Resty.Net makes my point clear, the RestRequest class can be utilized to do most of task that can be done through HttpWebRequest. I would dare to put it numerically that 90% of work that can be done using HttpWebRequest can also done using RestRequest of Resty.Net

No comments:

Post a Comment