asp.net core 2, razor pages 如何上传图片到磁盘

How to uploade images to disk in asp.net core 2 , razor pages

我是 asp.net 框架的初学者,但我非常鼓励学习和应用它。 https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/razor-pages-start

我跟着它,一切正常,我通过添加新模型,表格。

假设我们的电影模型是:

public class Movie
{
    public int ID { get; set; }
    public string Title { get; set; }
    public DateTime ReleaseDate { get; set; }
    public string Genre { get; set; }
    public decimal Price { get; set; }
}

下面是创建过程的代码:

public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        _context.Movie.Add(Movie);
        await _context.SaveChangesAsync();

        return RedirectToPage("./Index");
    }

以下是来自 :

的部分内容
        <div class="form-group">
            <label asp-for="Movie.Price" class="control-label"></label>
            <input asp-for="Movie.Price" class="form-control" />
            <span asp-validation-for="Movie.Price" class="text-danger"></span>
        </div>

现在我想在表单中添加一个新字段来上传 "Cover image",这样用户就可以浏览和 select 电影的封面图片以在相同的表单中上传它。

我的问题是:

要将图像路径存储在 table 中,您需要先将 属性 添加到您的实体 class 中,以便它会在您的 [=53= 中创建一个列].

public class Movie
{
    public int ID { get; set; }
    public string Title { get; set; }
    public DateTime ReleaseDate { get; set; }
    public string Genre { get; set; }
    public decimal Price { get; set; }
    public string ImageName  { set;get;}   // This is the new property
}

现在要从 UI 接收文件,您需要向 IFormFile

类型的 PageModel class 添加一个新的 属性
public class CreateModel : PageModel
{
    [BindProperty]
    public Movie Movie { set; get; }

    [BindProperty]
    public IFormFile Image { set; get; }
}

现在在您的表单中,添加类型为 file 的输入元素。确保你的表单标签有一个 enctype 属性并且它的值设置为 multipart/form-data

<form method="post" enctype="multipart/form-data"> 
    <div asp-validation-summary="All"></div>

    <input type="text" placeholder="Title" asp-for="Movie.Title"/>
    <input type="text" placeholder="Genre" asp-for="Movie.Genre" />
    <input type="text" placeholder="Price" asp-for="Movie.Price"/>
    <input type="file"  asp-for="Image"/>

    <button type="submit">Save</button>
</form>

现在在您的 OnPost 方法中,您可以读取页面模型的 Image 属性 值并将其保存到磁盘。在asp.net核心中,wwwroot目录是专门存放静态资源的目录。所以你可以把图像放在那个下面。我会在 wwwroot.

中创建一个名为 uploads 的子目录

要获取 wwwroot 目录的路径,您可以使用 IHostingEnvironment。所以将其注入您的页面模型 class.

public class CreateModel : PageModel
{
     private readonly YourDbContext context;
     private readonly IHostingEnvironment hostingEnvironment;
     public CreateModel(YourDbContext context,IHostingEnvironment environment)
     {
        this.hostingEnvironment = environment;
        this.context=context;
     }
    //Your existing code for properties goes here
    public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid)
            return Page();

        if (this.Image != null)
        {
            var fileName = GetUniqueName(this.Image.FileName); 
            var uploads = Path.Combine(hostingEnvironment.WebRootPath, "uploads");
            var filePath = Path.Combine(uploads,fileName);
            this.Image.CopyTo(new FileStream(filePath, FileMode.Create));
            this.Movie.ImageName = fileName; // Set the file name
        }
        context.Movie.Add(this.Movie);
        await context.SaveChangesAsync();
        return RedirectToPage("MovieList");
    }
    private string GetUniqueName(string fileName)
    {
        fileName = Path.GetFileName(fileName);
        return Path.GetFileNameWithoutExtension(fileName)
               + "_" + Guid.NewGuid().ToString().Substring(0, 4)
               + Path.GetExtension(fileName);
    }
}

这会将文件保存到 wwwroot/uploads 并将图像名称存储在我们正在保存的 Movie 记录的 ImageName 属性 中。所以当你想显示图像时,读取记录,并使用 ImageName 属性 并创建 url。 (例如:'yourSiteName/uploads/aaa_9521.jpg,其中 aaa_9521.jpg 将来自您的电影记录 ImageName 属性 值)

例如,在另一个页面中,您的页面模型有一个 Movies 属性,它是 Movie 个实体的集合,您可以这样做

<table>    
    @foreach (Movie m in Model.Movies)
    {
        <tr>
            <td>@m.Title</td>
            <td>@m.Price</td>
            <td>
                <img src="~/uploads/@m.ImageName"/>
            </td>
        </tr>
    }
</table>