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 th
You can simply convert your image to a Base64String then post it as a 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 on my code is the class/Model value to be converted to string
using Json.Serialize(model) which also contains your image System.Convert.ToBase64String(imageBytes[]) as its property.
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! :)
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
}
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);
}
If your API only allows one image at a time, System.Web.Helpers.WebImage
may help. Just make sure that a filename is included.
------WebKitFormBoundaryzrmNUJnUirtKajVF Content-Disposition: form-data; name="image"; filename="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.
}
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);
}
}
You Can Use This Sample To Upload Image In Web Api.
First create ImageWriterHelper
to check the file format
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;
}
}
Then you should create class for saving image
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 };
}
}
Next create class ImageResizeHelper
to resize the image
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);
}
}
At the end create action 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);
}
I Used constructor injection for creating an instance of classes
please see this link: Uploading Image To Server Using Web API 2.0