ASP.Net Core -- 文件上传

在做项目时候,一些表单要求有图片上传功能,今天总结一下在ASP.Net Core中如何实现图片上传功能。

实现功能:点击按钮或者文件选择框,选择图片,在input框内显示图片名称,点击保存,将图片上传到images文件夹,同时对图片名称重命名保存到数据库。

新建一个Student.cs:

public class Student
    {
        public int Id { get; set; }
        
        public string FirstName { get; set; }
        
        public string LastName { get; set; }
        
        public DateTime BirthDate { get; set; }
       
        public Gender Gender { get; set; }

        public string PhotoPath { get; set; }
    }

然后新建一个StudentCreateViewModel.cs

public class StudentCreateViewModel
    {
        [Display(Name = "姓"),Required]
        public string FirstName { get; set; }
        [Display(Name = "名"),Required,MaxLength(10)]
        public string LastName { get; set; }
        [Display(Name = "出生日期"), Required]
        public DateTime BirthDate { get; set; }
        [Display(Name = "性别")]
        public Gender Gender { get; set; }
        [Display(Name ="图片")]
        public IFormFile Photo { get; set; }
    }

这里边和Student.cs的字段一样,只不过Student.cs类文件的属性不够用,所以新建一个ViewModel

里边图片的类型是:IFormFile,为什么要用这个类型?现在对IFormFile进行反编译,如下:

public interface IFormFile
    {
        //
        // 摘要:
        //     Gets the raw Content-Type header of the uploaded file.
        string ContentType
        {
            get;
        }
        //
        // 摘要:
        //     Gets the raw Content-Disposition header of the uploaded file.
        string ContentDisposition
        {
            get;
        }
        //
        // 摘要:
        //     Gets the header dictionary of the uploaded file.
        IHeaderDictionary Headers
        {
            get;
        }
        //
        // 摘要:
        //     Gets the file length in bytes.
        long Length
        {
            get;
        }
        //
        // 摘要:
        //     Gets the form field name from the Content-Disposition header.
        string Name
        {
            get;
        }
        //
        // 摘要:
        //     Gets the file name from the Content-Disposition header.
        string FileName
        {
            get;
        }

        //
        // 摘要:
        //     Opens the request stream for reading the uploaded file.
        Stream OpenReadStream();
        //
        // 摘要:
        //     Copies the contents of the uploaded file to the target stream.
        //
        // 参数:
        //   target:
        //     The stream to copy the file contents to.
        void CopyTo(Stream target);
        //
        // 摘要:
        //     Asynchronously copies the contents of the uploaded file to the target stream.
        //
        // 参数:
        //   target:
        //     The stream to copy the file contents to.
        //
        //   cancellationToken:
        Task CopyToAsync(Stream target, CancellationToken cancellationToken = default(CancellationToken));
    }

可以看到,里边有很多重要的内容,其实它就是一个类型文件,比如可以读取文件,获取文件名称,类型,还可以将上传文件的内容复制到目标流等等...

然后新建视图,编写表单:

<form method="post" enctype="multipart/form-data">
    <div style="800px;margin:0 auto">
        <div class="form-group">
            <label asp-for="FirstName"></label>
            <input asp-for="FirstName" class="form-control" />
            <span asp-validation-for="FirstName"></span>
        </div>
        <div>
            <label asp-for="LastName"></label>
            <input asp-for="LastName" class="form-control" />
            <span asp-validation-for="LastName"></span>
        </div>
        <div>
            <label asp-for="BirthDate"></label>
            <input asp-for="BirthDate" type="date" class="form-control" />
            <span asp-validation-for="BirthDate"></span>
        </div>
        <div>
            <label asp-for="Gender"></label>
            <select asp-for="Gender" asp-items="Html.GetEnumSelectList<Gender>()" class="form-control">
            </select>
            <span asp-validation-for="Gender"></span>
        </div>
        <div>
            <label asp-for="Photo"></label>
            <div class="custom-file">
                <input asp-for="Photo" class="form-control custom-file-input" />
                <label class="custom-file-label">请选择照片....</label>
            </div>
        </div>
        <br />
        <input type="submit" value="save" class="btn btn-primary" />
    </div>
</form>

编写js代码,当选择图片后,获取路径,将图片名称显示在标签中,如下:

<script>
      $(document).ready(function () {
          $('.custom-file-input').on('change', function () {
              var fileName = $(this).val().split('\').pop();
              $(this).next('.custom-file-label').html(fileName);
          })
      })
</script>

控制器中接收表单内容,判断是否有图片上传,如果有,获取图片名称,对名称重命名编码,保存并保存到文件:

首先要使用到HostingEnvironment这个服务对象,因为它可以获取项目中的 绝对路径和相对路径,然后注入:

public readonly IRepository<Student> _repository;
        private readonly HostingEnvironment _hostingEnvironment;

        public HomeController(IRepository<Student> repository,HostingEnvironment hostingEnvironment)
        {
            _repository = repository;
            _hostingEnvironment = hostingEnvironment;
        }

然后实现:

public IActionResult Create(StudentCreateViewModel model)
        {
            if (ModelState.IsValid)
            {
                string uniqueFileName = null;

                if (model.Photo != null)
                {
                    //找到根目录下的wwwroot文件夹下的images文件夹
                    string uploadesFolder = Path.Combine(_hostingEnvironment.WebRootPath, "images");

                    //对图片名称进行重命名,防止重复
                    uniqueFileName = Guid.NewGuid().ToString() + "-" + model.Photo.FileName;

                    //将路径和新的图片名称合并
                    string filePath = Path.Combine(uploadesFolder, uniqueFileName);

                    //将图片复制到指定文件夹中
                    model.Photo.CopyTo(new FileStream(filePath, FileMode.Create));
                }

                var list = new Student
                {
                    FirstName = model.FirstName,
                    LastName = model.LastName,
                    BirthDate = model.BirthDate,
                    Gender = model.Gender,
                    PhotoPath= uniqueFileName
                };

                var newModel = _repository.Add(list);

                return RedirectToAction(nameof(Detail), new { id = newModel.Id });
            }
            return View();
        }

功能实现!

  

原文地址:https://www.cnblogs.com/dcy521/p/13563794.html