asp.net core MVC - framework net6.0
I have a page in which i upload an image and save it to the db.
the file i'm getting from the view is IFormFile.
I want to be able to check the resolution (width and height) of the photo before saving in DB.
Can it be done with IFormFile?
here is the controller that handles the file :
public JsonResult Submit(IFormFile PhotoFile)
{
int success = 0;
string excep = "";
try
{
if (PhotoFile.Length > 0)
{
using (var ms = new MemoryStream())
{
PhotoFile.CopyTo(ms);
var fileBytes = ms.ToArray();
}
}
ApplicationUser appUser =
_unitOfWork.ApplicationUser.GetAll().Where(a => a.UserName == User.Identity.Name).FirstOrDefault();
if (appUser != null)
{
FileUpload fileUpload = new FileUpload()
{
file = PhotoFile,
CompanyId = appUser.CompanyId
};
SaveFile(fileUpload);
}
excep = "success";
success = 1;
return Json(new { excep, success });
}
catch (Exception ex)
{
excep = "fail";
success = 0;
return Json(new { excep, success });
}
}
public string SaveFile(FileUpload fileObj)
{
Company company = _unitOfWork.Company.GetAll().
Where(a => a.Id == fileObj.CompanyId).FirstOrDefault();
if(company != null && fileObj.file.Length > 0)
{
using (var ms = new MemoryStream())
{
fileObj.file.CopyTo(ms);
var fileBytes = ms.ToArray();
company.PhotoAd = fileBytes;
_unitOfWork.Company.Update(company);
_unitOfWork.Save();
return "Saved";
}
}
return "Failed";
}
As far as I know this isn't possible with just IFormFile and you need System.Drawing.Common.
So first you need to convert it like:
using var image = Image.FromStream(PhotoFile.OpenReadStream());
Then you can simply get the height/width with image.height and image.width
Related
[HttpPost]
public async Task<IActionResult> UploadImage(ImageViewModel imageviewmodel, IFormFile Image)
{
var user = new AdminController(_context).GetUserId(Request);
if (user != null)
{
imageViewModel.Id = user.Id;
string name = $"{DateTime.UtcNow.Ticks}-";
if (Image == null || Image.Length == 0)
return Content("File not found");
var path = Path.Combine(
Directory.GetCurrentDirectory(), "wwwroot/Images", Image.FileName);
using (var stream = new FileStream(path, FileMode.Create))
{
await Image.CopyToAsync(stream);
string content_type = Image.ContentType;
}
imageviewmodel.Image = name + Image.FileName;
_context.ImageViewModels.Update(imageviewmodel);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
else
{
return Redirect("/Account/Login");
}
}
Hello All I am not able to upload multiple attachments with postman and I don't understand why
Here there is my Api in order to replace existing files
[HttpPost]
[Route("api/attachments/UpdateMultiple")]
public Result UpdateMultiple(List<int> id)
{
try
{
ATTACHMENT[] results = new ATTACHMENT[] { };
int position = 0;
foreach (int i in id)
{
var file = HttpContext.Current.Request.Files[position];
ATTACHMENT attachment = entities.ATTACHMENT.Where(a => a.IDATTACHMENT ==
i).FirstOrDefault();
byte[] fileBytes = new byte[] { };
using (var ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
fileBytes = ms.ToArray();
}
attachment.Binarydata= fileBytes;
attachment.TypeFILE = file.ContentType;
attachment.NAMEFILE = file.FileName;
entities.SaveChanges();
results[position] = (attachment);
position++;
}
return new Result("OK", results );
}
catch (Exception e)
{
return new Result("KO", + e);
}
}
Here Postman:
Any Suggestion? I have no Idea what to do
Try adding FromQueryAttribute/FromUriAttribute (depending on the ASP.NET version) to parameter:
public Result UpdateMultiple([FromQuery] List<int> id)
Or
public Result UpdateMultiple([FromUri] List<int> id)
UPD
ATTACHMENT[] results = new ATTACHMENT[] { }; creates an empty array, so accessing it by any index will throw an exception, change it to var results = new ATTACHMENT[id.Count];
Solved it with help of Guru Stron -thank you!
to fix, I had to add/modify:
public Result UpdateMultiple([FromUri] List<int> id){
List<ATTACHMENT> results = new List<ATTACHMENT>();
int pos = 0;
foreach (int i in id)
{
var file = HttpContext.Current.Request.Files[pos];
pos++;
[...]
results.Add(attachment);
[...]
}
}
Hi have a Xamarin Android project using C#. Currently I am using await CrossMedia.Current.PickPhotoAsync() method to upload image. However, it did not provide a tickbox beside the images for me to select multiple. How can I manage to select multiple images and upload together?
You could implement it by yourself.
1.Add these methods to your MainActivity.cs file
public static int OPENGALLERYCODE = 100;
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
//If we are calling multiple image selection, enter into here and return photos and their filepaths.
if (requestCode == OPENGALLERYCODE && resultCode == Result.Ok)
{
List<string> images = new List<string>();
if (data != null)
{
//Separate all photos and get the path from them all individually.
ClipData clipData = data.ClipData;
if (clipData != null)
{
for (int i = 0; i < clipData.ItemCount; i++)
{
ClipData.Item item = clipData.GetItemAt(i);
Android.Net.Uri uri = item.Uri;
var path = GetRealPathFromURI(uri);
if (path != null)
{
images.Add(path);
}
}
}
else
{
Android.Net.Uri uri = data.Data;
var path = GetRealPathFromURI(uri);
if (path != null)
{
images.Add(path);
}
}
}
}
}
/// <summary>
/// Get the real path for the current image passed.
/// </summary>
public String GetRealPathFromURI(Android.Net.Uri contentURI)
{
try
{
ICursor imageCursor = null;
string fullPathToImage = "";
imageCursor = ContentResolver.Query(contentURI, null, null, null, null);
imageCursor.MoveToFirst();
int idx = imageCursor.GetColumnIndex(MediaStore.Images.ImageColumns.Data);
if (idx != -1)
{
fullPathToImage = imageCursor.GetString(idx);
}
else
{
ICursor cursor = null;
var docID = DocumentsContract.GetDocumentId(contentURI);
var id = docID.Split(':')[1];
var whereSelect = MediaStore.Images.ImageColumns.Id + "=?";
var projections = new string[] { MediaStore.Images.ImageColumns.Data };
cursor = ContentResolver.Query(MediaStore.Images.Media.InternalContentUri, projections, whereSelect, new string[] { id }, null);
if (cursor.Count == 0)
{
cursor = ContentResolver.Query(MediaStore.Images.Media.ExternalContentUri, projections, whereSelect, new string[] { id }, null);
}
var colData = cursor.GetColumnIndexOrThrow(MediaStore.Images.ImageColumns.Data);
cursor.MoveToFirst();
fullPathToImage = cursor.GetString(colData);
}
return fullPathToImage;
}
catch (Exception ex)
{
Toast.MakeText(Xamarin.Forms.Forms.Context, "Unable to get path", ToastLength.Long).Show();
}
return null;
}
2.invoked the following in the specific Activity which you want to open the picker
public void OpenGallery()
{
try
{
var imageIntent = new Intent(Intent.ActionPick);
imageIntent.SetType("image/*");
imageIntent.PutExtra(Intent.ExtraAllowMultiple, true);
imageIntent.SetAction(Intent.ActionGetContent);
this.StartActivityForResult(Intent.CreateChooser(imageIntent, "Select photo"), OPENGALLERYCODE);
Toast.MakeText(this, "Tap and hold to select multiple photos.", ToastLength.Short).Show();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Toast.MakeText(this, "Error. Can not continue, try again.", ToastLength.Long).Show();
}
}
void ClearFileDirectory()
{
var directory = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures), ImageHelpers.collectionName).Path.ToString();
if (Directory.Exists(directory))
{
var list = Directory.GetFiles(directory, "*");
if (list.Length > 0)
{
for (int i = 0; i < list.Length; i++)
{
File.Delete(list[i]);
}
}
}
}
//collectionName is the name of the folder in your Android Pictures directory.
public static readonly string collectionName = "TmpPictures";
public string SaveFile(byte[] imageByte, string fileName)
{
var fileDir = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures), collectionName);
if (!fileDir.Exists())
{
fileDir.Mkdirs();
}
var file = new Java.IO.File(fileDir, fileName);
System.IO.File.WriteAllBytes(file.Path, imageByte);
return file.Path;
}
public string CompressImage(string path)
{
byte[] imageBytes;
//Get the bitmap.
var originalImage = BitmapFactory.DecodeFile(path);
//Set imageSize and imageCompression parameters.
var imageSize = .86;
var imageCompression = 67;
//Resize it and then compress it to Jpeg.
var width = (originalImage.Width * imageSize);
var height = (originalImage.Height * imageSize);
var scaledImage = Bitmap.CreateScaledBitmap(originalImage, (int)width, (int)height, true);
using (MemoryStream ms = new MemoryStream())
{
scaledImage.Compress(Bitmap.CompressFormat.Jpeg, imageCompression, ms);
imageBytes = ms.ToArray();
}
originalImage.Recycle();
originalImage.Dispose();
GC.Collect();
return SaveFile(imageBytes, Guid.NewGuid().ToString());
}
I, am using angular 5, with asp.net core 2.0. I, am trying to upload the file to the server. The code update the file to the server. But with 0 kb of data and sometime it upload the file.
The file size is not large. Its in KB.
Here is the Angular code
public QuestionPostHttpCall(_questionPhotoVM: QuestionPhotoViewModel): Observable<GenericResponseObject<QuestionPhotoViewModel[]>> {
const formData: FormData = new FormData();
formData.append('FileUpload', _questionPhotoVM.FileUpload);
formData.append('QuestionText', _questionPhotoVM.questionText);
formData.append('QuestionId', _questionPhotoVM.questionId);
const headers = new HttpHeaders().set('enctype', 'multipart/form-data');
return this._httpClientModule.post<GenericResponseObject<QuestionPhotoViewModel[]>>(this.questionPhotoUrl, formData);
}
In the controller I, can receive the file.
Here is the controller method
[HttpPost]
public JsonResult QuestionPhotoPost(IFormFile FileUpload, string QuestionText, Guid? QuestionId)
{
string TempFileName = string.Empty;
var directiveToUpload = Path.Combine(_environment.WebRootPath, "images\\UploadFile");
var http = HttpRequestExtensions.GetUri(Request);
QuestionViewModel model = new QuestionViewModel();
try
{
if (FileUpload != null)
{
TempFileName = FileUpload.FileName;
CheckFileFromFrontEnd();
}
}
catch (Exception exception)
{
}
void CheckFileFromFrontEnd()
{
if (FileUpload != null)
{
if (!System.IO.Directory.Exists(directiveToUpload))
{
System.IO.Directory.CreateDirectory(directiveToUpload);
}
if (System.IO.File.Exists(string.Format("{0}\\{1}\\{2}", _environment.WebRootPath, "images\\UploadFile", FileUpload.FileName)))
{
TempFileName = Guid.NewGuid().ToString() + FileUpload.FileName;
}
model.PictureUrl = string.Format("{0}://{1}/{2}/{3}/{4}", http.Scheme, http.Authority, "images", "UploadFile", TempFileName);
SaveFileToServer(TempFileName);
}
}
void SaveFileToServer(string FileName)
{
if (FileUpload.Length > 0)
{
using (var stream = new FileStream(Path.Combine(directiveToUpload, FileName), FileMode.Create))
{
FileUpload.CopyToAsync(stream);
}
}
}
return Json(genericResponseObject);
}
The file is uploaded to the server. But some time it upload with 0 byte and sometime it upload correctly.
The resolution of file is 570 X 400 and size of file 197KB
Where I, am doing wrong?? Please anyone let me know. Do, I need to specify max byte in somewhere ??
Your problem is that you are using an asynchronous function and not awaiting it.
You are using ASP.NET Core so you should (read "must") use the async-all-the-way pattern:
[HttpPost]
public async Task<JsonResult> QuestionPhotoPost(IFormFile FileUpload, string QuestionText, Guid? QuestionId)
{
string TempFileName = string.Empty;
var directiveToUpload = Path.Combine(_environment.WebRootPath, "images\\UploadFile");
var http = HttpRequestExtensions.GetUri(Request);
QuestionViewModel model = new QuestionViewModel();
try
{
if (FileUpload != null)
{
TempFileName = FileUpload.FileName;
await CheckFileFromFrontEndAsync();
}
}
catch (Exception exception)
{
}
async Task CheckFileFromFrontEndsync()
{
if (FileUpload != null)
{
if (!System.IO.Directory.Exists(directiveToUpload))
{
System.IO.Directory.CreateDirectory(directiveToUpload);
}
if (System.IO.File.Exists(string.Format("{0}\\{1}\\{2}", _environment.WebRootPath, "images\\UploadFile", FileUpload.FileName)))
{
TempFileName = Guid.NewGuid().ToString() + FileUpload.FileName;
}
model.PictureUrl = string.Format("{0}://{1}/{2}/{3}/{4}", http.Scheme, http.Authority, "images", "UploadFile", TempFileName);
await SaveFileToServerAsync(TempFileName);
}
}
async Task SaveFileToServerAsync(string FileName)
{
if (FileUpload.Length > 0)
{
using (var stream = new FileStream(Path.Combine(directiveToUpload, FileName), FileMode.Create))
{
await FileUpload.CopyToAsync(stream);
}
}
}
return Json(genericResponseObject);
}
To make the code more readable, I'd move those inline functions to outside, though.
if (imgUpload.HasFiles)
{
try
{
foreach (HttpPostedFile file in imgUpload.PostedFiles)
{
using (Stream fs = file.InputStream)
{
string fileType = file.ContentType;
if (fileType == "image/jpeg" || fileType == "image/jpg" || fileType == "image/gif" || fileType == "image/png" || fileType == "image/bmp")
{
int fileSize = file.ContentLength;
if (fileSize <= 10485760) //Max Size: 10MB
{
Session["imgUpload"] = imgUpload;
err = true;
}
else
{
lblStatus.Text = "<b style='color:red'>Please select a file of max size 2MB only.</b>";
err = false;
}
}
else
{
lblStatus.Text = "<b style='color:red'>Please select an image file only (Ex:*.jpg/*.jpeg/*.gif/*.png/*.bmp)</b>";
err = false;
}
}
}
}
catch (Exception)
{
lblStatus.Text = "<b style='color:red'>Some problem occurred while uploading the file. Please try after some time.</b>";
err = false;
}
}
protected void imgUpload2()
{
objImage = new ImageModel();
objOperation = new Operations();
if (Session["imgUpload"] != null && (!imgUpload.HasFile))
{
imgUpload = (FileUpload)Session["imgUpload"];
}
//else if (imgUpload.HasFile)
//{
// Session["FileUpload1"] = imgUpload;
//}
if (imgUpload.PostedFiles.Count > 0)
{
foreach (HttpPostedFile file in imgUpload.PostedFiles)
{
using (Stream fs = file.InputStream)
{
lblStatus.Visible = false;
using (BinaryReader br = new BinaryReader(fs))
{
byte[] bytes = br.ReadBytes((Int32)fs.Length);
objImage.ImageName = file.FileName;
objImage.ImageInByte = bytes;
var rs = objOperation.insertImage(objImage);
}
}
}
}
}
public int insertImage(ImageModel objImage)
{
var result = MySqlHelper.ExecuteNonQuery(Common.GetConnection(), CommandType.StoredProcedure, ConstantFields.StoredProcedureClass.sp_insertImage,
new MySqlParameter("image_name",objImage.ImageName),
new MySqlParameter("image_byteImage", objImage.ImageInByte)
);
return result;
}
Stored Procedure:
BEGIN
set #ad_id:=(select max(ad_id) from postadverties p,user_register u
where p.ad_userid=u.user_id);
insert into images(image_name,image_byteImage,image_adid)
values(image_name,image_byteImage,#ad_id);
END
Above is my code to insert the images in database.I have called the imgUpload2() on button click.Issue is when i am trying to insert images the names of images gets inserted but longblob field in database table shows 0 bytes.So please help to find out what is the real issue.
Thank's in advance.