如何通过WebApi上传图片

时间:2015-08-05 17:49:48

标签: c# asp.net-web-api

如何通过 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);
   }
}

6 个答案:

答案 0 :(得分:18)

这里我描述了在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);
    }
}

答案 1 :(得分:8)

在WEB API Post Controller上设置此代码(取自http://www.c-sharpcorner.com/uploadfile/fc9f65/uploading-a-file-with-web-api-and-entity-framework-using-aja/):

    // 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");
}
嘿,让我知道它是否适合你!乐于帮助! :)

答案 2 :(得分:3)

WebApi 支持反序列化 JSON 数组,以便您可以通过使用byte[]声明来接收字节数。

以下示例将说明如何上传图片:

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

在你的控制器中。将图像写入磁盘:

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("~/")将提供服务器运行的内部路径。 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);
 }

答案 3 :(得分:2)

您只需将图片转换为 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 [])作为其属性。

答案 4 :(得分:2)

您可以使用此示例在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);
            }
        }

最后在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);
        }

我使用构造函数注入来创建类的实例

please see this link: Uploading Image To Server Using Web API 2.0

答案 5 :(得分:1)

如果您的API一次只允许一张图片,System.Web.Helpers.WebImage可能有所帮助。只需确保包含文件名。

------ WebKitFormBoundaryzrmNUJnUirtKajVF 内容处理:表格数据;命名=&#34;图像&#34 ;;的文件名=&#34; IMG_3321.JPG&#34; 内容类型: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.
}