简体   繁体   English

ASP.NET内核如何上传文件?

[英]How to upload files in ASP.NET Core?

How to upload files or images using ASP.NET MVC 6 with some model data?如何使用 ASP.NET MVC 6 和一些 model 数据上传文件或图像?

For 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?此外,是否有任何用于重新调整大小和图像水印的图像处理库与 Codeigniter 图像处理 class 相同? ( https://codeigniter.com/user_guide/libraries/image_lib.html ( https://codeigniter.com/user_guide/libraries/image_lib.html

You can add a new property of type IFormFile to your view model您可以将IFormFile类型的新属性添加到您的视图模型

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.在您的 GET 操作方法中,我们将创建此视图模型的对象并将其发送到视图。

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"现在在你的创建视图中,它是强类型到我们的视图模型,有一个form标签,它的enctype属性设置为"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 操作

[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.如果要将文件上传到应用程序中的某个目录,则应使用IHostingEnvironment获取 webroot 路径。 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)这会将文件保存到应用程序的wwwwroot目录中的uploads文件夹中,并使用 Guids 生成的随机文件名(以防止覆盖同名文件)

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.在这里,我们使用了一个非常简单的GetUniqueName方法,它将从 guid 添加 4 个字符到文件名的末尾,使其有点独特。 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 ?您是否应该将上传图像的完整 url 存储在数据库中?

No. Do not store the full url to the image in the database.不。不要在数据库中存储图像的完整 url。 What if tomorrow your business decides to change your company/product name from www.thefacebook.com to www.facebook.com ?如果明天您的企业决定将您的公司/产品名称从www.thefacebook.com更改为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.您应该存储上面生成的唯一文件名(我们上面使用的uniqueFileName变量)来存储文件名。 When you want to display the image back, you can use this value (the filename) and build the url to the image.当您想要显示图像时,您可以使用此值(文件名)并构建图像的 url。

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.我只是将图像名称硬编码到imgFileName变量并使用它。 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如果要将文件作为 bytearray/varbinary 保存到数据库中,可以像这样将IFormFile对象转换为字节数组

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.现在,在您的 http post 操作方法中,您可以调用此方法从IFormFile生成字节数组并使用它来保存到您的表中。 the below example is trying to save a Post entity object using entity framework.下面的示例尝试使用实体框架保存 Post 实体对象。

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

Fileservice.cs : Fileservice.cs

public class FileService : IFileService
{
    private readonly IWebHostEnvironment env;

    public FileService(IWebHostEnvironment env)
    {
        this.env = env;
    }

    public string Upload(IFormFile file)
    {
        var uploadDirecotroy = "uploads/";
        var uploadPath = Path.Combine(env.WebRootPath, uploadDirecotroy);

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

        var fileName = Guid.NewGuid() + Path.GetExtension(file.FileName);
        var filePath = Path.Combine(uploadPath, fileName);

        using (var strem = File.Create(filePath))
        {
            file.CopyTo(strem);
        }
        return fileName;
    }
}

IFileService : IFileService

namespace studentapps.Services
{
    public interface IFileService
    {
        string Upload(IFormFile file);
    }
}

StudentController : StudentController

[HttpGet]
public IActionResult Create()
{
    var student = new StudentCreateVM();
    student.Colleges = dbContext.Colleges.ToList();
    return View(student);
}

[HttpPost]
public IActionResult Create([FromForm] StudentCreateVM vm)
{
    Student student = new Student()
    {
        DisplayImage = vm.DisplayImage.FileName,
        Name = vm.Name,
        Roll_no = vm.Roll_no,
        CollegeId = vm.SelectedCollegeId,
    };


    if (ModelState.IsValid)
    {
        var fileName = fileService.Upload(vm.DisplayImage);
        student.DisplayImage = fileName;
        getpath = fileName;

        dbContext.Add(student);
        dbContext.SaveChanges();
        TempData["message"] = "Successfully Added";
    }
    return RedirectToAction("Index");
}
        foreach (var formFile in files)
        {
            if (formFile.Length > 0)
            {
                var FilePath = _configuration.GetValue<string>("FilesPath:Cases");
                string FileName = Guid.NewGuid().ToString() + Path.GetExtension(formFile.FileName);
                string SavePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot" + FilePath, FileName);

                using (var stream = System.IO.File.Create(SavePath))
                {
                    formFile.CopyTo(stream);
                }
            }
        }

you can try below code你可以试试下面的代码

1- model or view model 1-模型或视图模型

public class UploadImage 
{
  public string ImageFile { get; set; }
  public string ImageName { get; set; }
  public string ImageDescription { get; set; }
}

2- View page 2- 查看页面

<form class="form-horizontal" asp-controller="Image" asp-action="UploadImage" method="POST" enctype="multipart/form-data">

<input type="file" asp-for="ImageFile">
<input type="text" asp-for="ImageName">
<input type="text" asp-for="ImageDescription">
</form>

3- Controller 3- 控制器

 public class Image
    {

      private IHostingEnvironment _hostingEnv;
      public Image(IHostingEnvironment hostingEnv)
      {
         _hostingEnv = hostingEnv;
      }

      [HttpPost]
      public async Task<IActionResult> UploadImage(UploadImage model, IFormFile ImageFile)
      {
        if (ModelState.IsValid)
         {
        var filename = ContentDispositionHeaderValue.Parse(ImageFile.ContentDisposition).FileName.Trim('"');
        var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images", ImageFile.FileName);
        using (System.IO.Stream stream = new FileStream(path, FileMode.Create))
         {
            await ImageFile.CopyToAsync(stream);
         }
          model.ImageFile = filename;
         _context.Add(model);
         _context.SaveChanges();
         }        

      return RedirectToAction("Index","Home");   
    }

Controller Code:-控制器代码:-

 public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;

    private IHostingEnvironment _environment;
    public HomeController(ILogger<HomeController> logger,IHostingEnvironment environment)
    {
        _logger = logger;
        _environment = environment;
    }

    public IActionResult Index()
    {
        return View();
    }
    [HttpPost]
    public IActionResult uploader()
    {
        var filelist = HttpContext.Request.Form.Files;
        if(filelist.Count>0)
        {
            foreach(var file in filelist)
            {

            var uploads = Path.Combine(_environment.WebRootPath, "files");
            string FileName = file.FileName;
            using (var fileStream = new FileStream(Path.Combine(uploads, FileName), FileMode.Create))
            {
                file.CopyToAsync(fileStream);
            }                    
            }
        }
        return View("Index");
    }
  
}

View Code:-查看代码:-

@using (Html.BeginForm("uploader", "Home", FormMethod.Post, new { enctype = multipart/form-data" }))

{ {

<input type="file" multiple name="file" />
<input type="submit" value="Upload" />

} }

How to upload files in asp.net core如何在asp.net core中上传文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM