How to Upload Image Via WebApi

How I can upload Image File via ASP.NET Web API?
I have an input tag in File mode and it posted to API, how I can save it to server folder?
I tried this code but it doesn't worked:

private void UploadWholeFile(HttpRequestBase request)
{
   for (int i = 0; i < request.Files.Count; i++)
   {
      var file = request.Files[i];

      var ext = new FileInfo(file.FileName).Extension;
      var fullPath = Path.Combine(StorageRoot, Path.GetFileName(Guid.NewGuid() + ext));

      file.SaveAs(fullPath);
   }
}

Solution 1:

Here i have described the whole process to upload the image in web api

[Route("user/PostUserImage")]
public async Task<HttpResponseMessage> PostUserImage()
{
    Dictionary<string, object> dict = new Dictionary<string, object>();
    try
    {

        var httpRequest = HttpContext.Current.Request;

        foreach (string file in httpRequest.Files)
        {
            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created);

            var postedFile = httpRequest.Files[file];
            if (postedFile != null && postedFile.ContentLength > 0)
            {

                int MaxContentLength = 1024 * 1024 * 1; //Size = 1 MB

                IList<string> AllowedFileExtensions = new List<string> { ".jpg", ".gif", ".png" };
                var ext = postedFile.FileName.Substring(postedFile.FileName.LastIndexOf('.'));
                var extension = ext.ToLower();
                if (!AllowedFileExtensions.Contains(extension))
                {

                    var message = string.Format("Please Upload image of type .jpg,.gif,.png.");

                    dict.Add("error", message);
                    return Request.CreateResponse(HttpStatusCode.BadRequest, dict);
                }
                else if (postedFile.ContentLength > MaxContentLength)
                {

                    var message = string.Format("Please Upload a file upto 1 mb.");

                    dict.Add("error", message);
                    return Request.CreateResponse(HttpStatusCode.BadRequest, dict);
                }
                else
                {

                    YourModelProperty.imageurl = userInfo.email_id + extension;
                    //  where you want to attach your imageurl

                    //if needed write the code to update the table

                    var filePath = HttpContext.Current.Server.MapPath("~/Userimage/" + userInfo.email_id + extension);
                    //Userimage myfolder name where i want to save my image
                    postedFile.SaveAs(filePath);

                }
            }

            var message1 = string.Format("Image Updated Successfully.");
            return Request.CreateErrorResponse(HttpStatusCode.Created, message1); ;
        }
        var res = string.Format("Please Upload a image.");
        dict.Add("error", res);
        return Request.CreateResponse(HttpStatusCode.NotFound, dict);
    }
    catch (Exception ex)
    {
        var res = string.Format("some Message");
        dict.Add("error", res);
        return Request.CreateResponse(HttpStatusCode.NotFound, dict);
    }
}

Solution 2:

Set this code (taken from http://www.c-sharpcorner.com/uploadfile/fc9f65/uploading-a-file-with-web-api-and-entity-framework-using-aja/) on the WEB API Post Controller:

    // POST: api/FileUploads
    [ResponseType(typeof(FileUpload))]
    public IHttpActionResult PostFileUpload()
    {
        if (HttpContext.Current.Request.Files.AllKeys.Any())
        {
            // Get the uploaded image from the Files collection  
            var httpPostedFile = HttpContext.Current.Request.Files["UploadedImage"];
            if (httpPostedFile != null)
            {
                FileUpload imgupload = new FileUpload();
                int length = httpPostedFile.ContentLength;
                imgupload.imagedata = new byte[length]; //get imagedata  
                httpPostedFile.InputStream.Read(imgupload.imagedata, 0, length);
                imgupload.imagename = Path.GetFileName(httpPostedFile.FileName);
                db.FileUploads.Add(imgupload);
                db.SaveChanges();
                // Make sure you provide Write permissions to destination folder
                string sPath = @"C:\Users\xxxx\Documents\UploadedFiles";
                var fileSavePath = Path.Combine(sPath, httpPostedFile.FileName);
                // Save the uploaded file to "UploadedFiles" folder  
                httpPostedFile.SaveAs(fileSavePath);
                return Ok("Image Uploaded");
            }
        }
        return Ok("Image is not Uploaded"); 
    }

On your UWP application, set the following method:

    using System;
    using System.Threading.Tasks;
    using Windows.Storage;
    using Windows.Storage.Streams;
    using Windows.Web.Http;
    // ...
    public static bool UploadImageToServer(StorageFile imageFile)
    {
        bool saveRes = false;
        try
        {
            using (HttpClient client = new HttpClient())
            {
                if (client != null) // if no Network Connection
                {
                    HttpResponseMessage response = new HttpResponseMessage();
                    Task task = Task.Run(async () =>
                    {
                        using (HttpMultipartFormDataContent formData = new HttpMultipartFormDataContent())
                        {
                            IBuffer buffer = await FileIO.ReadBufferAsync(imageFile);
                            HttpBufferContent WebHTTPContent = new HttpBufferContent(buffer);
                            formData.Add(WebHTTPContent, "UploadedImage", imageFile.Name);
                            response = await client.PostAsync(App.VehicleImageUri, formData);
                            if (response.IsSuccessStatusCode) saveRes = true;
                        }
                    });
                    task.Wait();
                }
            }
        }
        catch (Exception em)
        {
           // Handle exception here ... 
        }
        return saveRes;
    }

You call your method as follows:

private async void CaptureImageByUser()
{
    StorageFile file;

    // Create storage file in local app storage
    string fileName = GenerateNewFileName() + ".jpg";
    CreationCollisionOption collisionOption = CreationCollisionOption.GenerateUniqueName;

    file = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(fileName, collisionOption);

    // Captures and stores new Jpeg image file
    await mediaCapture.CapturePhotoToStorageFileAsync(ImageEncodingProperties.CreateJpeg(), file);
    // Delete the file in the temporary location if successfully uploaded
    if (SaveDataByUser.UploadImageToServer(file)) await file.DeleteAsync();
}

private string GenerateNewFileName(string prefix = "IMG")
{
    return prefix + "_" + DateTime.UtcNow.ToString("yyyy-MMM-dd_HH-mm-ss");
}

Hey, let me know if it works for you!! Happy to help! :)

Solution 3:

WebApi supports deserializing JSON array, so that you can receive bytes by declaring with byte[].

The following example will show how to upload image:

public class ImageModel
{
    public string Name { get; set; }
    public byte[] Bytes { get; set; }
}

In your controller. Writing image to disk:

private string WriteImage(byte[] arr)
{
    var filename = $@"images\{DateTime.Now.Ticks}.";

    using (var im = Image.FromStream(new MemoryStream(arr)))
    {
        ImageFormat frmt;
        if (ImageFormat.Png.Equals(im.RawFormat))
        {
            filename += "png";
            frmt = ImageFormat.Png;
        }
        else
        {
            filename += "jpg";
            frmt = ImageFormat.Jpeg;
        }
        string path = HttpContext.Current.Server.MapPath("~/") + filename;
        im.Save(path, frmt);
    }

    return $@"http:\\{Request.RequestUri.Host}\{filename}";
}

HttpContext.Current.Server.MapPath("~/") will give the internal path of server running. Request.RequestUri.Host returns the hostname.

public IHttpActionResult UploadImage(ImageModel model)
{
    var imgUrl = WriteImage(model.Bytes);

    // Some code
}

To send image from browser

In HTML:

<input type="file" id="imageFile"/>

Upload method for AngularJS:

$scope.upload = function () {

     var file = document.getElementById("imageFile").files[0];
     var r = new FileReader();
     r.onloadend = function (e) {


         var arr = Array.from(new Uint8Array(e.target.result));

         var uploadData = {
             Name: "Name of Image",
             Bytes: arr
         }
         console.log(uploadData);

         $http.post('api/Uploader/UploadImage', uploadData)
         .then(
         function (response) {
             console.log(response);
         },

         function (reason) {

             console.log(reason);
         })
     }
     r.readAsArrayBuffer(file);
 }