ASP.NET Core上传图片

11

我是ASP.net Core的新手,我想上传一个文件(一张图片)并将其存储在特定文件夹中。我一直在按照此教程进行操作(ASP.NET Core中的文件上传),但我不知道如何将其存储在文件中,它只是被上传到服务器上。

<form method="post" enctype="multipart/form-data" asp-controller="UploadFiles" asp-action="Index">
<div class="form-group">
    <div class="col-md-10">
        <p>Upload one or more files using this form:</p>
        <input type="file" name="files" multiple />
    </div>
</div>
<div class="form-group">
    <div class="col-md-10">
        <input type="submit" value="Upload" />
    </div>
</div>

这是控制器

[HttpPost("UploadFiles")]
public async Task<IActionResult> Post(List<IFormFile> files)
{
long size = files.Sum(f => f.Length);

// full path to file in temp location
var filePath = Path.GetTempFileName();

foreach (var formFile in files)
{
    if (formFile.Length > 0)
    {
        using (var stream = new FileStream(filePath, FileMode.Create))
        {
            await formFile.CopyToAsync(stream);
        }
    }
}

// process uploaded files
// Don't rely on or trust the FileName property without validation.

return Ok(new { count = files.Count, size, filePath});
}

这是我正在使用的类

public interface IFormFile
{
string ContentType { get; }
string ContentDisposition { get; }
IHeaderDictionary Headers { get; }
long Length { get; }
string Name { get; }
string FileName { get; }
Stream OpenReadStream();
void CopyTo(Stream target);
Task CopyToAsync(Stream target, CancellationToken cancellationToken = null);
}

我只需要将图片存储在文件夹中,例如:C:\Users\DESKTOP-1603\Desktop\GestionSyndic\GestionSyndic\src\WebApplication1\wwwroot\images\并更改图片的名称。谢谢:D


我们使用 IFormFile.OpenReadStream() 和 ImageSharp 来验证它是否为真实的图像文件。如果您不需要此功能,可以使用以下方法:https://dev59.com/B3RC5IYBdhLWcg3wFdJx - DogeAmazed
你说的“存储到文件中”,是指要将其存储在应用程序根目录下的特定文件夹中吗? - Shyju
抱歉,我是指我的应用程序根目录中的文件夹。 - DevTest28
3个回答

17

ASP.NET Core MVC简易文件上传步骤

1. Demo.cshtml视图代码片段

<form method="post" enctype="multipart/form-data" asp-controller="Demo" asp-action="Index">
<div class="form-group">
    <div class="col-md-10">
        <p>Upload one or more files using this form:</p>
        <input type="file" name="files" multiple />
    </div>
</div>
<div class="form-group">
    <div class="col-md-10">
        <input type="submit" value="Upload" />
    </div>
</div>

为了展示演示,我创建了一个Demo控制器,其中包含2个操作方法:一个用于处理GET请求,另一个用于处理POST请求。

  1. DemoController(演示控制器)

为了展示演示,我创建了一个Demo控制器,其中包含2个操作方法:一个用于处理GET请求,另一个用于处理POST请求。

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using System;
using System.IO;
using System.Net.Http.Headers;

namespace WebApplication6.Controllers
{
    public class DemoController : Controller
    {
        private readonly IHostingEnvironment _environment;

        // Constructor
        public DemoController(IHostingEnvironment IHostingEnvironment)
        {
            _environment = IHostingEnvironment;
        }

        [HttpGet]
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public IActionResult Index(string name)
        {
            var newFileName = string.Empty;

            if (HttpContext.Request.Form.Files != null)
            {
                var fileName = string.Empty;
                string PathDB = string.Empty;

                var files = HttpContext.Request.Form.Files;

                foreach (var file in files)
                {
                    if (file.Length > 0)
                    {
                        //Getting FileName
                        fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');

                        //Assigning Unique Filename (Guid)
                        var myUniqueFileName = Convert.ToString(Guid.NewGuid());

                        //Getting file Extension
                        var FileExtension = Path.GetExtension(fileName);

                        // concating  FileName + FileExtension
                        newFileName = myUniqueFileName + FileExtension;

                        // Combines two strings into a path.
                        fileName = Path.Combine(_environment.WebRootPath, "demoImages") + $@"\{newFileName}";

                        // if you want to store path of folder in database
                        PathDB = "demoImages/" + newFileName;

                        using (FileStream fs = System.IO.File.Create(fileName))
                        {
                            file.CopyTo(fs);
                            fs.Flush();
                        }
                    }
                }


            }
            return View();
        }
    }
}

调试时的快照

调试时的快照

存储图像的文件夹位置

存储图像的文件夹位置


感谢您的回复。我现在面临的问题是,我已经添加了这段代码,但我只能提交照片,模型不再在控制器中提交。 - DevTest28
问题是我没有收到任何错误,传递给控制器的模型为空。这里是整个问题:https://stackoverflow.com/questions/47319242/adding-photo-and-model?noredirect=1#comment81611148_47319242 - DevTest28
1
这段代码不具备可移植性,反斜杠只在Windows中有效,请始终使用Path.Combine(): path += $@"\{newFileName}"; // 错误的方式 - ManuelJE
1
这段代码可以工作,只有在更新“fileName”时会出现异常。这行代码在我的Mac上可以工作: fileName = Path.Combine(_environment.WebRootPath, "uploadImages") + $@"/{newFileName}"; - Jeff

5

您应该注入IHostingEnvironment,以便获取Web根目录(默认为wwwroot)的位置。

public class HomeController : Controller
{
    private readonly IHostingEnvironment hostingEnvironment;
    public HomeController(IHostingEnvironment environment)
    {
        hostingEnvironment = environment;
    }
    [HttpPost]
    public async Task<IActionResult> UploadFiles(List<IFormFile> files)
    {
        long size = files.Sum(f => f.Length);

        // full path to file in temp location
        var filePath = Path.GetTempFileName();

        foreach (var formFile in files)
        {
            var uploads = Path.Combine(hostingEnvironment.WebRootPath, "images");
            var fullPath = Path.Combine(uploads, GetUniqueFileName(formFile.FileName));
            formFile.CopyTo(new FileStream(fullPath, FileMode.Create));

        }
        return Ok(new { count = files.Count, size, filePath });
    }
    private string GetUniqueFileName(string fileName)
    {
        fileName = Path.GetFileName(fileName);
        return  Path.GetFileNameWithoutExtension(fileName)
                  + "_" 
                  + Guid.NewGuid().ToString().Substring(0, 4) 
                  + Path.GetExtension(fileName);
    }
}

这将把文件保存到 wwwroot 目录下的 images 文件夹。

确保你的表单标签的 action 属性设置为 HomeController 的 UploadFiles 动作方法(/Home/UploadFiles)。

<form method="post" enctype="multipart/form-data" asp-controller="Home"
                                                  asp-action="UploadFiles">
    <div class="form-group">
        <div class="col-md-10">
            <p>Upload one or more files using this form:</p>
            <input type="file" name="files" multiple />
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-10">
            <input type="submit" value="Upload" />
        </div>
    </div>
</form>

我不太确定你为什么想要返回“Ok”结果。你可以考虑返回一个重定向结果到列表页面。


0

我刚刚使用了@Saineshwar的被采纳答案,但是进行了一些重构,将其作为一个扩展方法,以便更容易地使用IFromFile

public static string MakeFileUniqueName(this IFormFile formFile)
    {
        if (formFile.Length > 0)
        {
            string fileName =
                ContentDispositionHeaderValue.Parse(formFile.ContentDisposition).FileName.Trim('"');

            // concatinating  FileName + FileExtension
            return Guid.NewGuid() + Path.GetExtension(fileName);      
        }

        return string.Empty;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接