欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Core上传图片

程序员文章站 2024-01-21 18:57:40
...

Core上传单个图片和多个图片 编辑图片

一、单个文件上传

类需要加一个字段为:类型为 IFormFile

[Display(Name = "头像")]
 public IFormFile Photo{get;set;}

IFormFile类中属性以及方法

名称 内容
ContentType 获取上传文件的原始Content-Type标头
ContentDisposition 获取上传文件的原始Content-Disposition标头
Length 获取文件长度,以字节为单位
FileName 从Content-Disposition标头中获取的文件名
Name 从Content-Disposition标头中获取的字段名称
Headers 获取上传文件的HTTP消息头的字典信息
OpenReadStream() 打开请求流以读取上传的文件
CopyTo() 将上传文件的内容复制粘贴到流
CopyToAsync() 异步地将上传文件的内容复制粘贴到流

页面:表单元素应设置为enctype=“multipart/form-data”

 @* 我们使用asp-for的TagHelper设置input的属性为Photo
 Photo属性类型是IFormFile,所以在运行的时候ASP.NET Core会将该标签生成上传控件(input type=file)*@
<div class="form-group row">
 	<label asp-for="Photo" class="col-sm-2 col-form-label"> </label>
 	<div class="col-sm-10">
		 <div class="custom-file">
			 <input asp-for="Photo" multiple class="form-control custom-fileinput"/>
 				<label class="custom-file-label">请选择图片....</label>
 		</div>
 	 </div>
 </div>
 @*以下JavaScript代码的作用是,可以在上传标签中显示选定的上传文件名称。*@
 
 @section Scripts{
            <script>
                $(document).ready(function () {
                    $(".custom-file-input").on("change",function () {
                        var fileName = $(this)
                            .val()
                            .split("\\")
                            .pop();
                        $(this)
                            .next(".custom-file-label")
                            .html(fileName);
                    });
                });
            </script>
        }

控制器:


[HttpPost]
 public IActionResult Create(StudentCreateViewModel model)
 {		
 		//模型验证判断是否通过
		 if(ModelState.IsValid)
		 {
			 string uniqueFileName = null;
			 //判断图片是否存在
			 if(model.Photo!= null)
			 {
				//必须将图片文件上传到wwwroot的images文件夹中
				//而要获取wwwroot文件夹的路径,我们需要注入ASP.NET Core提供的WebHostEnvironment服务    
				 string uploadsFolder = Path.Combine(_webHostEnvironment.WebRootPath,"images");
				 
				 //为了确保文件名是唯一的,我们在文件名后附加一个新的GUID值和一个下划线
				 uniqueFileName = Guid.NewGuid().ToString() + "_" + model.Photo.FileName;
				 string filePath = Path.Combine(uploadsFolder,uniqueFileName);
				 
				 //使用IFormFile接口提供的CopyTo()方法将文件复制到wwwroot/images文件夹
				 model.Photo.CopyTo(new FileStream(filePath,FileMode.Create));
			 }
				 //封装 
				 Student newStudent = new Student
				 {
					 Name = model.Name,
					 Email = model.Email,
					 Major = model.Major,
					 // 将文件名保存在Student对象的PhotoPath属性中
					 //它将被保存到数据库Students的表中
					 PhotoPath = uniqueFileName
				 };
				 
				 // 调用添加的接口
				 _studentRepository.Insert(newStudent);
				return RedirectToAction("Details"new{id = newStudent.Id});
		 }
		 return View();
 }

二、多个文件上传

页面:表单元素应设置为enctype=“multipart/form-data”

 @* 我们使用asp-for的TagHelper设置input的属性为Photo
 Photo属性类型是IFormFile,所以在运行的时候ASP.NET Core会将该标签生成上传控件(input type=file)*@
 <div class="form-group row">
            <label asp-for="ClassName" class="col-sm-2 col-form-label">年纪:</label>
            <select asp-for="ClassName" asp-items="Html.GetEnumSelectList<ClassNameEnum>()" 
              class="form-control custom-select mr-sm-2">
                <option value="">请选择</option>
            </select>
            <span asp-validation-for="ClassName" class="text-danger"></span>

        </div>

   @*当上传一个文件时显示文件名,当上传多个文件时则显示文件数量*@
        @section Scripts{
                <script>
                    $(document).ready(function () {
                        $(".custom-file-input").on("change",function () {
                            //console.log($(this));
                            var fileLabel = $(this).next(".custom-file-label");
                            var files = $(this)[0].files;
                            if (files.length > 1) {
                                fileLabel.html("靓仔已经选择了:" + files.length + " 个文件");
                            } else if (files.length == 1) {
                                fileLabel.html(files[0].name);
                            }
                        });
                    });
                </script>
        }
//类需要改为 List<IFormFile>类型
 [Display(Name = "头像")]
  public List<IFormFile> Photos { get; set; }

上传

  	   [HttpPost]
        public IActionResult Create(StudentCreateViewModel model)
        {
            if (ModelState.IsValid)
            {
                string uniqueFileName = null;
                
                if (model.Photos != null && model.Photos.Count() > 0)
                {
                    foreach (IFormFile photo in model.Photos)
                    {
                        //必须将图片文件上传到wwwroot的images/avatars文件夹中而要获取wwwroot文件夹的
                        //路径,我们需要注入ASP.NET Core提供的WebHost Environment 服务通过
                        //WebHostEnvironment服务获取wwwroot文件夹的路径
                        string uploadsFolder = Path.Combine(_webHostEnvironment.WebRootPath, "avatars");
                        //为了确保文件名是唯一的,我们在文件名后附加一个新的GUID值和一个下划线                  
                        uniqueFileName = Guid.NewGuid().ToString() + "_" + photo.FileName;
                        string filePath = Path.Combine(uploadsFolder, uniqueFileName);
                        //使用IFormFile接口提供的CopyTo()方法将文件复制到wwwroot/images/avatars文件夹
                        photo.CopyTo(new FileStream(filePath, FileMode.Create));
                    }

                }
                Student newStudent = new Student
                {
                    Name = model.Name,
                    Email = model.Email,
                    Major = model.Major,
                    ClassName = model.ClassName,
                    // 将文件名保存在Student对象的PhotoPath属性中
                    //它将被保存到数据库Students的表中
                    PhotoPath = uniqueFileName,
                };
                _studentRepository.AddStudent(newStudent);
                return RedirectToAction("Detail", new { id = newStudent.Id });

            }
            return View();

        }

三.编辑用户

 		[HttpPost]
        public IActionResult Edit(StudentEditViewModel model)
        {
            Student student = _studentRepository.GetStudentById(model.Id);
            //判断页面验证是否通过
            if (ModelState.IsValid)
            {
                student.ClassName = model.ClassName;
                student.Email = model.Email;
                student.Id = model.Id;
                student.Major = model.Major;
                student.Name = model.Name;

				//判断是否修改了图片
                if (!string.IsNullOrEmpty(model.ExistingPhotoPath))
                {
                    //当文件存在的情况把旧的删除
                    if (model.ExistingPhotoPath != null)
                    {
                        string filePath = Path.Combine(_webHostEnvironment.WebRootPath, "images", 	"avatars", model.ExistingPhotoPath);
                        System.IO.File.Delete(filePath);

                    }
                    //我们将新的图片文件保存到wwwroot/images/avatars文件夹中,并且会更新
                    //Student对象中的PhotoPath属性,最终都会将它们保存到数据库中
                    //这里添加了一个私有方法 ProcessUploadedFile(),
                    student.PhotoPath = ProcessUploadedFile(model);

                }
                Student updatedstudent = _studentRepository.Update(student);

                return RedirectToAction("index");

            };

            return View(model);

        }
        

        

这里添加了一个私有方法 ProcessUploadedFile(),


		/// <summary>
        /// 上传图片私有方法
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private string ProcessUploadedFile(StudentEditViewModel model)
        {
            string uniqueFileName = null;

            if (model.Photos.Count > 0)
            {
                foreach (var photo in model.Photos)
                {
                    //必须将图片文件上传到wwwroot的images/avatars文件夹中
                    //而要获取wwwroot文件夹的路径,我们需要注入ASP.NET Core提供的webHostEnvironment服务
                    //通过webHostEnvironment服务去获取wwwroot文件夹的路径
                    string uploadsFolder = Path.Combine(_webHostEnvironment.WebRootPath, "images", "avatars");

                    //为了确保文件名是唯一的,我们在文件名后附加一个新的GUID值和一个下划线

                    uniqueFileName = Guid.NewGuid().ToString() + "_" + photo.FileName;
                    string filePath = Path.Combine(uploadsFolder, uniqueFileName);

                    //因为使用了非托管资源,所以需要手动进行释放
                    using (var fileStream = new FileStream(filePath, FileMode.Create))
                    {
                        //使用IFormFile接口提供的CopyTo()方法将文件复制到
                        //wwwroot/images/avatars文件夹
                        photo.CopyTo(fileStream);
                    }


                }

            }
            return uniqueFileName;
        }

这是一个通用方法,很适合作为工具方法。该方法中唯一要注意的是,我
们使用了FileStream,这是一个非托管资源,因此需要使用using来进行内存的释放,否
则会出现以下异常。

System.IO.IOException
 HResult=0x80070020
 Message=The process cannot access the file 'C:\Source\
MockSchoolManagement\wwwroot\images\avatars\93308bf7-ccb0-4966-9aa7-
5f23324a170b_man1.png' because it is being used by another process.
 Source=System.IO.FileSystem

要复现该错误,只需要将using(){}删除,然后对同一个学生进行连续两次图片修改操
作即可。

相关标签: Core