ASP.Net Core -- 檔案上傳
阿新 • • 發佈:2020-08-26
在做專案時候,一些表單要求有圖片上傳功能,今天總結一下在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="width: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();
}
功能實現!