Core上传图片

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
MockSchoolManagementwwwrootimagesavatars93308bf7-ccb0-4966-9aa7-
5f23324a170b_man1.png' because it is being used by another process.
 Source=System.IO.FileSystem

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

原文地址:https://www.cnblogs.com/rouehang/p/14597564.html