How To Upload And Save Image Or File Using Asp.Net WebApi? – Server Side (Part 1)

In this post, i am going to explain how to upload and save image or file using Asp.Net WebApi.
Key Notes regarding the code:
1. HttpResponseMessage: A HttpResponseMessage enables us to work with the HTTP convention. In straightforward words a HttpResponseMessage is a method for restoring a message/information from your activity.
2. EXIF Orientation: It changes the orientation of the picture and image captured by mobile phone. To handle this problem, refer to the below snipets.

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;

namespace WebApplication1.Controllers
{
    public class FileController : ApiController
    {
        public enum MessageType
        {
            Image = 0,
            File = 1
        }

        /// <summary>
        /// Purpose: Upload file or image
        /// </summary>
        [HttpPost]
        public HttpResponseMessage UploadFileOrImage()
        {
            if (!Request.Content.IsMimeMultipartContent())
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);

            try
            {
                var httpRequest = HttpContext.Current.Request;

                int attachmentType;
                int.TryParse(httpRequest.Form["AttachmentType"], out attachmentType);
                var fileName = httpRequest.Form["FileName"];

                string attachedPath = string.Empty;

                // Check if any file(s) have been uploaded
                if (httpRequest.Files.Count > 0)
                {
                    // Get file content as byte array
                    MemoryStream ms = new MemoryStream();
                    httpRequest.Files[0].InputStream.CopyTo(ms);
                    byte[] fileContent = ms.ToArray();

                    if (fileContent != null)
                    {
                        if (attachmentType == (int)MessageType.Image)
                        {
                            attachedPath = SaveImage(fileContent, "Uploads/Image/", true,
                                "Uploads/ImageThumb/", 90, 90);
                        }
                        else //Save File
                        {
                            var file = httpRequest.Files[0];
                            attachedPath = SaveFile(file, System.Web.Hosting.HostingEnvironment.MapPath("/Uploads/File/"));
                        }
                    }
                }

                var attachmentPath = "http://lazycipher.com/Uploads/ImageThumb/" + attachedPath;
                return Request.CreateResponse(HttpStatusCode.Created, attachmentPath);
            }
            catch (Exception ex)
            {
                return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.InnerException);
            }
        }

        #region Save Image

        /// <summary>
        /// Purpose: To Save Image
        /// </summary>
        /// <param name="File">Image Name</param>
        /// <param name="ImageSaveLocationPath"></param>
        /// <param name="ThumbnailCreate"></param>
        /// <param name="ImageThumbLocationPath"></param>
        /// <param name="thumbImageWidth"></param>
        /// <param name="thumbImageHeight"></param>
        /// <returns></returns>
        public static string SaveImage(byte[] File, string ImageSaveLocationPath, bool ThumbnailCreate = false,
            string ImageThumbLocationPath = "", int thumbImageWidth = 0, int thumbImageHeight = 0)
        {
            try
            {
                var sitePhysicalPath = AppDomain.CurrentDomain.BaseDirectory;

                string imageName = DateTime.Now.Ticks + ".jpg"; //Image Name
                string fileExtention = Path.GetExtension(imageName); // File Extension
                string ImagePhysicalPath = sitePhysicalPath + ImageSaveLocationPath + imageName; // Original Image Physical Path
                string OrginalImagePathLocation = ImageSaveLocationPath;

                byte[] bt = File;
                MemoryStream ms = new MemoryStream(bt);

                SaveOriginalImage(ms, ImagePhysicalPath);

                #region Save Thumbnails

                if (ThumbnailCreate)
                {
                    Bitmap ThumbImage = CreateThumbnail(sitePhysicalPath + OrginalImagePathLocation + imageName, thumbImageWidth, thumbImageHeight);
                    ImageThumbLocationPath += imageName.Substring(0, imageName.LastIndexOf('.')) + fileExtention;
                    ThumbImage.Save(sitePhysicalPath + ImageThumbLocationPath);
                }

                #endregion

                return imageName;
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// Purpose: Save original image
        /// </summary>
        /// <param name="ms"></param>
        /// <param name="ImagePhysicalPath"></param>
        private static void SaveOriginalImage(MemoryStream ms, string ImagePhysicalPath)
        {
            Image img = Image.FromStream(ms);
            img.Save(ImagePhysicalPath, ImageFormat.Jpeg);
        }


        /// <summary>
        /// Purpose: To save image as thumbnail
        /// </summary>
        /// <param name="lcFilename"></param>
        /// <param name="lnWidth"></param>
        /// <param name="lnHeight"></param>
        /// <returns></returns>
        private static Bitmap CreateThumbnail(string lcFilename, int lnWidth, int lnHeight)
        {
            Bitmap bmpOut = null;
            try
            {
                Bitmap loBMP = new Bitmap(lcFilename);
                ImageFormat loFormat = loBMP.RawFormat;

                decimal lnRatio;
                int lnNewWidth = 0;
                int lnNewHeight = 0;

                //*** If the image is smaller than a thumbnail just return it
                if (loBMP.Width < lnWidth && loBMP.Height < lnHeight) return loBMP; if (loBMP.Width > loBMP.Height)
                {
                    lnRatio = (decimal)lnWidth / loBMP.Width;
                    lnNewWidth = lnWidth;
                    decimal lnTemp = loBMP.Height * lnRatio;
                    lnNewHeight = (int)lnTemp;
                }
                else
                {
                    lnRatio = (decimal)lnHeight / loBMP.Height;
                    lnNewHeight = lnHeight;
                    decimal lnTemp = loBMP.Width * lnRatio;
                    lnNewWidth = (int)lnTemp;
                }

                #region Handle EXIF problem (i.e. When image clicked from camera, it automatically gets rotated)

                if (Array.IndexOf(loBMP.PropertyIdList, 274) > -1)
                {
                    var orientation = (int)loBMP.GetPropertyItem(274).Value[0];
                    switch (orientation)
                    {
                        case 1:
                            // No rotation required.
                            break;
                        case 2:
                            loBMP.RotateFlip(RotateFlipType.RotateNoneFlipX);
                            break;
                        case 3:
                            loBMP.RotateFlip(RotateFlipType.Rotate180FlipNone);
                            break;
                        case 4:
                            loBMP.RotateFlip(RotateFlipType.Rotate180FlipX);
                            break;
                        case 5:
                            loBMP.RotateFlip(RotateFlipType.Rotate90FlipX);
                            break;
                        case 6:
                            loBMP.RotateFlip(RotateFlipType.Rotate90FlipNone);
                            break;
                        case 7:
                            loBMP.RotateFlip(RotateFlipType.Rotate270FlipX);
                            break;
                        case 8:
                            loBMP.RotateFlip(RotateFlipType.Rotate270FlipNone);
                            break;
                    }
                    // This EXIF data is now invalid and should be removed.
                    loBMP.RemovePropertyItem(274);
                }

                #endregion

                bmpOut = new Bitmap(lnNewWidth, lnNewHeight);

                Graphics g = Graphics.FromImage(bmpOut);
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                g.FillRectangle(Brushes.White, 0, 0, lnNewWidth, lnNewHeight);
                g.DrawImage(loBMP, 0, 0, lnNewWidth, lnNewHeight);

                loBMP.Dispose();
            }
            catch
            {
                return null;
            }

            return bmpOut;
        }

        /// <summary>
        /// Purpose: Save file i.e. docs, xlsx etc
        /// </summary>
        /// <param name="file"></param>
        /// <param name="physicalPath"></param>
        /// <returns></returns>
        public static string SaveFile(HttpPostedFile file, string physicalPath)
        {
            if (file != null && file.ContentLength > 0)
            {
                var fileName = Path.GetFileName(file.FileName);
                var path = Path.Combine(physicalPath, fileName);
                file.SaveAs(path);

                return fileName;
            }

            return string.Empty;
        }

        #endregion
    }
}


If you have any problems or feedback or any idea leave a comment…

Part 2 of this post is coming soon, in which i will explain how to upload data from client side to server.

Comments

Popular posts from this blog

How To Detect Listview Scroll State (Idle/Running) In Xamarin.Forms?

Generic Web Api Client Request (GET/POST)