Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to upload files in asp.net core?

How to upload files or images using Asp.net MVC 6 with some model data? Example, I have a form like this;

<form>     <input type="file">     <input type="text" placeholder="Image name...">     <input type="text" placeholder="Image description...">     <input type="submit" value="Submit"> </form> 

I read many Tutorials in how to upload but I don't see anything uploading with some data like the form above.

Also, is there any library for image manipulation for re-sizing and Image Watermarking same as Codeigniter image manipulation class? (https://codeigniter.com/user_guide/libraries/image_lib.html

like image 877
kszyrver Avatar asked Feb 13 '16 11:02

kszyrver


People also ask

How do I upload a file using .NET core?

In order to support file uploads, HTML forms must specify an encoding type ( enctype ) of multipart/form-data . The individual files uploaded to the server can be accessed through Model Binding using IFormFile. The sample app demonstrates multiple buffered file uploads for database and physical storage scenarios.

How do I upload multiple files to .NET core?

Uploading Multiple files in ASP.NET Core MVC To Upload multiple files, navigate to " HomeController. cs " and now in the arguments we will take multiple files using "List<IFormFile>" and we will loop through each file to save it on physical drive.


2 Answers

You can add a new property of type IFormFile to your view model

public class CreatePost {    public string ImageCaption { set;get; }    public string ImageDescription { set;get; }    public IFormFile MyImage { set; get; } } 

and in your GET action method, we will create an object of this view model and send to the view.

public IActionResult Create() {    return View(new CreatePost()); } 

Now in your Create view which is strongly typed to our view model, have a form tag which has the enctype attribute set to "multipart/form-data"

@model CreatePost <form asp-action="Create" enctype="multipart/form-data">         <input asp-for="ImageCaption"/>     <input asp-for="ImageDescription"/>     <input asp-for="MyImage"/>      <input type="submit"/> </form> 

And your HttpPost action to handle the form posting

[HttpPost] public IActionResult Create(CreatePost model) {    var img = model.MyImage;    var imgCaption = model.ImageCaption;     //Getting file meta data    var fileName = Path.GetFileName(model.MyImage.FileName);    var contentType = model.MyImage.ContentType;     // do something with the above data    // to do : return something } 

If you want to upload the file to some directory in your app, you should use IHostingEnvironment to get the webroot path. Here is a working sample.

public class HomeController : Controller {     private readonly IHostingEnvironment hostingEnvironment;     public HomeController(IHostingEnvironment environment)     {         hostingEnvironment = environment;     }     [HttpPost]     public IActionResult Create(CreatePost model)     {         // do other validations on your model as needed         if (model.MyImage != null)         {             var uniqueFileName = GetUniqueFileName(model.MyImage.FileName);             var uploads = Path.Combine(hostingEnvironment.WebRootPath, "uploads");             var filePath = Path.Combine(uploads,uniqueFileName);             model.MyImage.CopyTo(new FileStream(filePath, FileMode.Create));               //to do : Save uniqueFileName  to your db table            }         // to do  : Return something         return RedirectToAction("Index","Home");     }     private string GetUniqueFileName(string fileName)     {         fileName = Path.GetFileName(fileName);         return  Path.GetFileNameWithoutExtension(fileName)                   + "_"                    + Guid.NewGuid().ToString().Substring(0, 4)                    + Path.GetExtension(fileName);     } } 

This will save the file to uploads folder inside wwwwroot directory of your app with a random file name generated using Guids ( to prevent overwriting of files with same name)

Here we are using a very simple GetUniqueName method which will add 4 chars from a guid to the end of the file name to make it somewhat unique. You can update the method to make it more sophisticated as needed.

Should you be storing the full url to the uploaded image in the database ?

No. Do not store the full url to the image in the database. What if tomorrow your business decides to change your company/product name from www.thefacebook.com to www.facebook.com ? Now you have to fix all the urls in the table!

What should you store ?

You should store the unique filename which you generated above(the uniqueFileName varibale we used above) to store the file name. When you want to display the image back, you can use this value (the filename) and build the url to the image.

For example, you can do this in your view.

@{     var imgFileName = "cats_46df.png"; } <img src="~/uploads/@imgFileName"  alt="my img"/> 

I just hardcoded an image name to imgFileName variable and used that. But you may read the stored file name from your database and set to your view model property and use that. Something like

<img src="~/uploads/@Model.FileName"  alt="my img"/> 

Storing the image to table

If you want to save the file as bytearray/varbinary to your database, you may convert the IFormFile object to byte array like this

private byte[] GetByteArrayFromImage(IFormFile file) {     using (var target = new MemoryStream())     {         file.CopyTo(target);         return target.ToArray();     } } 

Now in your http post action method, you can call this method to generate the byte array from IFormFile and use that to save to your table. the below example is trying to save a Post entity object using entity framework.

[HttpPost] public IActionResult Create(CreatePost model) {     //Create an object of your entity class and map property values     var post=new Post() { ImageCaption = model.ImageCaption };      if (model.MyImage != null)     {        post.Image =  GetByteArrayFromImage(model.MyImage);     }     _context.Posts.Add(post);     _context.SaveChanges();     return RedirectToAction("Index","Home"); } 
like image 152
Shyju Avatar answered Sep 20 '22 19:09

Shyju


 <form class="col-xs-12" method="post" action="/News/AddNews" enctype="multipart/form-data">       <div class="form-group">         <input type="file" class="form-control" name="image" />      </div>       <div class="form-group">         <button type="submit" class="btn btn-primary col-xs-12">Add</button>      </div>   </form> 

My Action Is

        [HttpPost]         public IActionResult AddNews(IFormFile image)         {             Tbl_News tbl_News = new Tbl_News();             if (image!=null)             {                  //Set Key Name                 string ImageName= Guid.NewGuid().ToString() + Path.GetExtension(image.FileName);                  //Get url To Save                 string SavePath = Path.Combine(Directory.GetCurrentDirectory(),"wwwroot/img",ImageName);                  using(var stream=new FileStream(SavePath, FileMode.Create))                 {                     image.CopyTo(stream);                 }             }             return View();         } 
like image 23
Diako Hasani Avatar answered Sep 23 '22 19:09

Diako Hasani