I am spinning up my 1st WebApi application and I have 2 questions about how to deal with images.
1) What are the different ways to POST/GET images to my service? I think I can either use Base-64 text in JSON or stay native as binary. My understanding is that by converting the image into text, there is a significant increase is package size.
2) If I send the image (from a web form, from a native client, from another service), should I add a Image Controller/Handler or use a Formatter? Is this even an either/or question?
I have researched StackOverflow and Google and came up with lots of examples:
Image TO the Service (POST) Controller:
http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-2 http://code.msdn.microsoft.com/Uploading-large-files-386ec0af#content
Formatter: http://jflood.net/tag/mediatypeformatter/
Image FROM the Service (GET) Controller: http://www.dotnetcurry.com/ShowArticle.aspx?ID=856 ASP .Net Web API downloading images as binary http://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/ Formatter:
http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters
Image TO AND FROM Controller: http://www.codeguru.com/csharp/.net/returning-images-from-asp.net-web-api.htm
Formatter: http://byterot.blogspot.com/2012/04/aspnet-web-api-series-part-5.html
I am not sure which direction I should be heading. Is the a site/blog article that lays out the pros and cons for this? And I haven't even looked at WebApi V2 to see if that has a different way to think about this.
Thanks in advance
I did some research and you can see the implementation I came up with here: http://jamessdixon.wordpress.com/2013/10/01/handling-images-in-webapi/
For preservation's sake - here's the outline of what Jamie's blog said:
Use a Controller:
Get:
public HttpResponseMessage Get(int id) { var result = new HttpResponseMessage(HttpStatusCode.OK); String filePath = HostingEnvironment.MapPath("~/Images/HT.jpg"); FileStream fileStream = new FileStream(filePath, FileMode.Open); Image image = Image.FromStream(fileStream); MemoryStream memoryStream = new MemoryStream(); image.Save(memoryStream, ImageFormat.Jpeg); result.Content = new ByteArrayContent(memoryStream.ToArray()); result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); return result; }
Delete:
public void Delete(int id) { String filePath = HostingEnvironment.MapPath("~/Images/HT.jpg"); File.Delete(filePath); }
Post:
public HttpResponseMessage Post() { var result = new HttpResponseMessage(HttpStatusCode.OK); if (Request.Content.IsMimeMultipartContent()) { //For larger files, this might need to be added: //Request.Content.LoadIntoBufferAsync().Wait(); Request.Content.ReadAsMultipartAsync( new MultipartMemoryStreamProvider()).ContinueWith((task) => { MultipartMemoryStreamProvider provider = task.Result; foreach (HttpContent content in provider.Contents) { Stream stream = content.ReadAsStreamAsync().Result; Image image = Image.FromStream(stream); var testName = content.Headers.ContentDisposition.Name; String filePath = HostingEnvironment.MapPath("~/Images/"); //Note that the ID is pushed to the request header, //not the content header: String[] headerValues = (String[])Request.Headers.GetValues("UniqueId"); String fileName = headerValues[0] + ".jpg"; String fullPath = Path.Combine(filePath, fileName); image.Save(fullPath); } }); return result; } else { throw new HttpResponseException(Request.CreateResponse( HttpStatusCode.NotAcceptable, "This request is not properly formatted")); } }