Как загрузить изображение через WebApi

Как я могу загрузить файл изображения через ASP.NET Web API?
У меня есть тег ввода в режиме файла, и он опубликован в API, как я могу сохранить его в папке сервера?
Я пробовал этот код, но он не работал:

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);
   }
}

Ответ 1

Здесь я описал весь процесс загрузки изображения в веб-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);
    }
}

Ответ 2

Установите этот код (взят из http://www.c-sharpcorner.com/uploadfile/fc9f65/uploading-a-file-with-web-api-and-entity-framework-using-aja/) в Посте WEB API контроллер:

    // 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"); 
    }

В вашем приложении UWP установите следующий метод:

    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;
    }

Вы называете свой метод следующим образом:

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");
}

Эй, дайте мне знать, если это работает для вас! Рад был помочь! :)

Ответ 3

WebApi поддерживает десериализацию массива JSON, так что вы можете получать байты, объявляя с помощью byte[].

В следующем примере показано, как загрузить изображение:

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

В вашем контроллере. Запись изображения на диск:

private string WriteImage(byte[] arr)
{
    var filename = [email protected]"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 [email protected]"http:\\{Request.RequestUri.Host}\{filename}";
}

HttpContext.Current.Server.MapPath("~/") предоставит внутренний путь работы сервера. Request.RequestUri.Host возвращает имя хоста.

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

    // Some code
}

Чтобы отправить изображение из браузера

В HTML:

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

Способ загрузки для 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);
 }

Ответ 4

Вы можете просто преобразовать свое изображение в Base64String, а затем разместить его как StringContent.

public static async Task<T> Post<T>(string controller, string method, string accessToken, string bodyRequest) where T : class
{
    using (HttpClient client = new HttpClient())
    {
        client.DefaultRequestHeaders.Clear();
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

        var stringContent = new StringContent(bodyRequest, Encoding.UTF8, "application/json");

        var response = await client.PostAsync($"{Constants.ApiBaseUrl}/api/{controller}/{method}", stringContent);
        if (response.IsSuccessStatusCode)
            return response.Content as T;
    }
    return default(T);
}

bodyRequest в моем коде - это значение класса/модели, которое должно быть преобразовано в строку

используя Json.Serialize(model), который также содержит ваше изображение System.Convert.ToBase64String (imageBytes []) как его свойство.

Ответ 5

Вы можете использовать этот образец для загрузки изображения в Web Api.

Сначала создайте ImageWriterHelper чтобы проверить формат файла

  public class ImageWriterHelper
        {
            public enum ImageFormat
            {
                Bmp,
                Jpeg,
                Gif,
                Tiff,
                Png,
                Unknown
            }

        public static ImageFormat GetImageFormat(byte[] bytes)
        {
            var bmp = Encoding.ASCII.GetBytes("BM");
            var gif = Encoding.ASCII.GetBytes("GIF");
            var png = new byte[] { 137, 80, 78, 71 };
            var tiff = new byte[] { 73, 73, 42 };
            var tiff2 = new byte[] { 77, 77, 42 };
            var jpeg = new byte[] { 255, 216, 255, 224 };
            var jpeg2 = new byte[] { 255, 216, 255, 225 };

            if (bmp.SequenceEqual(bytes.Take(bmp.Length)))
                return ImageFormat.Bmp;

            if (gif.SequenceEqual(bytes.Take(gif.Length)))
                return ImageFormat.Gif;

            if (png.SequenceEqual(bytes.Take(png.Length)))
                return ImageFormat.Png;

            if (tiff.SequenceEqual(bytes.Take(tiff.Length)))
                return ImageFormat.Tiff;

            if (tiff2.SequenceEqual(bytes.Take(tiff2.Length)))
                return ImageFormat.Tiff;

            if (jpeg.SequenceEqual(bytes.Take(jpeg.Length)))
                return ImageFormat.Jpeg;

            if (jpeg2.SequenceEqual(bytes.Take(jpeg2.Length)))
                return ImageFormat.Jpeg;

            return ImageFormat.Unknown;
        }
        }

Затем вы должны создать класс для сохранения изображения

  public class AddCandidateProfilePictureCommand:     
                                       IAddCandidateProfilePictureCommand
       {
        public AddCandidateProfilePictureResponse Execute(HttpPostedFile 
       postedFile)
        {
            byte[] fileBytes;

            using (var memoryStream = new MemoryStream())
            {
                postedFile.InputStream.CopyTo(memoryStream);
                fileBytes = memoryStream.ToArray();
            }

            if (ImageWriterHelper.GetImageFormat(fileBytes) == 
                ImageWriterHelper.ImageFormat.Unknown)
                throw new BadImageFormatException();

            var extension = Path.GetExtension(postedFile.FileName);
            var tempCandidateImageName = Guid.NewGuid();
            var fileName = $"{tempCandidateImageName}{extension}";
            var fileUrl =              
    WebConfigurationManager.AppSettings["CandidateProfilePictureAddress"];

            var filePath = Path.Combine(fileUrl, fileName);

            if (!Directory.Exists(fileUrl))
                Directory.CreateDirectory(fileUrl);

            postedFile.SaveAfterResizeImage(filePath, extension);

            return new AddCandidateProfilePictureResponse { 
                      TempCandidateImageName = fileName };
        }
        }

Затем создайте класс ImageResizeHelper для изменения размера изображения

 public static class ImageResizeHelper
        {
            public static void SaveAfterResizeImage( this HttpPostedFile 
                               postedFile,string filePath, string extension)
            {
                postedFile.SaveAs(filePath);

                var resizeSetting = new ResizeSettings
                {
                    Width = 500,
                    Height = 500,
                    Format = extension
                };

                ImageBuilder.Current.Build(filePath,ilePath,resizeSetting);
            }
        }

В конце создайте действие In Controller

  [HttpPost]
        public IHttpActionResult AddCandidateProfilePicture()
        {
            var request = HttpContext.Current.Request;
            const int maxContentLength = 512 * 512 * 1;

            if (request.ContentLength > maxContentLength || 
                request.Files.Count == 0)
                return BadRequest();

            var pictureFile = request.Files[0];

            var result = 
AddCandidateProfilePictureCommand.Execute(pictureFile);

            return Ok(result);
        }

Я использовал инжектор конструктора для создания экземпляра классов

перейдите по этой ссылке: Загрузка изображения на сервер с помощью Web API 2.0

Ответ 6

Если ваш API допускает только одно изображение за раз, может помочь System.Web.Helpers.WebImage. Просто убедитесь, что включено имя файла.

------ WebKitFormBoundaryzrmNUJnUirtKajVF Content-Disposition: form-data; name= "образ"; имя_файла = "IMG_3321.JPG" Content-Type: image/jpeg

------ WebKitFormBoundaryzrmNUJnUirtKajVF -

[HttpPost]
[ResponseType(typeof(Models.Photo))]
[Route("upload")]
public async Task<IHttpActionResult> Upload()
{
    var img = WebImage.GetImageFromRequest();
    if (img == null)
    {
        return BadRequest("Image is null.");
    }

    // Do whatever you want with the image (resize, save, ...)

    // In this case, I save the image to a cloud storage and
    // create a DB record to reference the image.
}