如何在asp.net核心上传文件?

ryz*_*hie 23 c# image-manipulation file-upload asp.net-core-mvc

如何使用Asp.net MVC 6上传文件或图像以及一些模型数据?例如,我有一个这样的表格;

<form>
    <input type="file">
    <input type="text" placeholder="Image name...">
    <input type="text" placeholder="Image description...">
    <input type="submit" value="Submit">
</form>
Run Code Online (Sandbox Code Playgroud)

我阅读了许多关于如何上传的教程,但我没有看到任何上传的内容与上面的表格一样.

另外,是否存在用于重新调整大小和图像水印的图像处理库,与Codeigniter图像处理类相同?(https://codeigniter.com/user_guide/libraries/image_lib.html

Shy*_*yju 63

您可以IFormFile向视图模型添加类型的新属性

public class CreatePost
{
   public string ImageCaption { set;get; }
   public string ImageDescription { set;get; }
   public IFormFile MyImage { set; get; }
}
Run Code Online (Sandbox Code Playgroud)

在您的GET操作方法中,我们将创建此视图模型的对象并发送到视图.

public IActionResult Create()
{
   return View(new CreatePost());
}
Run Code Online (Sandbox Code Playgroud)

现在,在我们的视图模型中强类型的"创建"视图中,有一个属性设置为的form标记enctype"multipart/form-data"

@model CreatePost
<form asp-action="Create" enctype="multipart/form-data">   

    <input asp-for="ImageCaption"/>
    <input asp-for="ImageDescription"/>
    <input asp-for="MyImage"/>

    <input type="submit"/>
</form>
Run Code Online (Sandbox Code Playgroud)

和你的HttpPost动作来处理表单发布

[HttpPost]
public IActionResult Create(CreatePost model)
{
   var img = model.MyImage;
   var imgCaption = model.ImageCaption;

   //Getting file meta data
   var fileName = Path.GetFileName(model.MyImage.FileName);
   var contentType = model.MyImage.ContentType;

   // do something with the above data
   // to do : return something
}
Run Code Online (Sandbox Code Playgroud)

如果要将文件上载到应用程序中的某个目录,则应使用IHostingEnvironment获取webroot路径.这是一个工作样本.

public class HomeController : Controller
{
    private readonly IHostingEnvironment hostingEnvironment;
    public HomeController(IHostingEnvironment environment)
    {
        hostingEnvironment = environment;
    }
    [HttpPost]
    public IActionResult Create(CreatePost model)
    {
        // do other validations on your model as needed
        if (model.MyImage != null)
        {
            var uniqueFileName = GetUniqueFileName(model.MyImage.FileName);
            var uploads = Path.Combine(hostingEnvironment.WebRootPath, "uploads");
            var filePath = Path.Combine(uploads,uniqueFileName);
            model.MyImage.CopyTo(new FileStream(filePath, FileMode.Create)); 

            //to do : Save uniqueFileName  to your db table   
        }
        // to do  : Return something
        return RedirectToAction("Index","Home");
    }
    private string GetUniqueFileName(string fileName)
    {
        fileName = Path.GetFileName(fileName);
        return  Path.GetFileNameWithoutExtension(fileName)
                  + "_" 
                  + Guid.NewGuid().ToString().Substring(0, 4) 
                  + Path.GetExtension(fileName);
    }
}
Run Code Online (Sandbox Code Playgroud)

这将使用Guids生成的随机文件名将文件保存到应用程序目录中的文件uploadswwwwroot(以防止覆盖具有相同名称的文件)

这里我们使用一个非常简单的GetUniqueName方法,它将guid中的4个字符添加到文件名的末尾,使其有些独特.您可以根据需要更新方法以使其更复杂.

您是否应该将完整的URL存储到数据库中的上传图像?

不.不要将完整的URL存储到数据库中的图像中.如果明天您的公司决定将您的公司/产品名称更改为,www.thefacebook.comwww.facebook.com 怎么办?现在你必须修复表中的所有网址!

你应该存储什么?

您应该存储上面生成的唯一文件名(我们上面使用uniqueFileNamevaribale)来存储文件名.如果要显示图像,可以使用此值(文件名)并为图像构建URL.

例如,您可以在视图中执行此操作.

@{
    var imgFileName = "cats_46df.png";
}
<img src="~/uploads/@imgFileName"  alt="my img"/>
Run Code Online (Sandbox Code Playgroud)

我只是将图像名称硬编码为imgFileName变量并使用它.但是,您可以从数据库中读取存储的文件名,并将其设置为视图模型属性并使用它.就像是

<img src="~/uploads/@Model.FileName"  alt="my img"/>
Run Code Online (Sandbox Code Playgroud)

将图像存储到表格中

如果要将文件保存为bytearray/varbinary到数据库,可以将IFormFile对象转换为字节数组,如下所示

private byte[] GetByteArrayFromImage(IFormFile file)
{
    using (var target = new MemoryStream())
    {
        file.CopyTo(target);
        return target.ToArray();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,在http post动作方法中,您可以调用此方法生成字节数组,IFormFile并使用它保存到表中.下面的示例尝试使用实体框架保存Post实体对象.

[HttpPost]
public IActionResult Create(CreatePost model)
{
    //Create an object of your entity class and map property values
    var post=new Post() { ImageCaption = model.ImageCaption };

    if (model.MyImage != null)
    {
       post.Image =  GetByteArrayFromImage(model.MyImage);
    }
    _context.Posts.Add(post);
    _context.SaveChanges();
    return RedirectToAction("Index","Home");
}
Run Code Online (Sandbox Code Playgroud)

  • 你的表单有`enctype ="multipart/form-data"? (4认同)
  • 如果我将 `enctype="multipart/form-data"` 添加到我的表单中,此解决方案对我不起作用。知道可能是什么问题吗?IFormFile 始终为空。 (2认同)
  • 检查您的财产是否有“set;”。还要确保输入文件名与您的属性名称匹配。 (2认同)
  • 使用上面的代码,我发现在使用`FileMode.Create`之后关闭文件很有帮助,否则创建了一个.net使用的0kb文件,直到我停止调试`var newfile = new FileStream(filePath,FileMode.CreateNew);为止。file.CopyTo(newfile); newfile.Close();` (2认同)

Dia*_*ani 18

 <form class="col-xs-12" method="post" action="/News/AddNews" enctype="multipart/form-data">

     <div class="form-group">
        <input type="file" class="form-control" name="image" />
     </div>

     <div class="form-group">
        <button type="submit" class="btn btn-primary col-xs-12">Add</button>
     </div>
  </form>
Run Code Online (Sandbox Code Playgroud)

我的行动是

        [HttpPost]
        public IActionResult AddNews(IFormFile image)
        {
            Tbl_News tbl_News = new Tbl_News();
            if (image!=null)
            {

                //Set Key Name
                string ImageName= Guid.NewGuid().ToString() + Path.GetExtension(image.FileName);

                //Get url To Save
                string SavePath = Path.Combine(Directory.GetCurrentDirectory(),"wwwroot/img",ImageName);

                using(var stream=new FileStream(SavePath, FileMode.Create))
                {
                    image.CopyTo(stream);
                }
            }
            return View();
        }
Run Code Online (Sandbox Code Playgroud)


小智 5

Fileservice.cs

public class FileService : IFileService
{
    private readonly IWebHostEnvironment env;

    public FileService(IWebHostEnvironment env)
    {
        this.env = env;
    }

    public string Upload(IFormFile file)
    {
        var uploadDirecotroy = "uploads/";
        var uploadPath = Path.Combine(env.WebRootPath, uploadDirecotroy);

        if (!Directory.Exists(uploadPath))
            Directory.CreateDirectory(uploadPath);

        var fileName = Guid.NewGuid() + Path.GetExtension(file.FileName);
        var filePath = Path.Combine(uploadPath, fileName);

        using (var strem = File.Create(filePath))
        {
            file.CopyTo(strem);
        }
        return fileName;
    }
}
Run Code Online (Sandbox Code Playgroud)

IFileService

namespace studentapps.Services
{
    public interface IFileService
    {
        string Upload(IFormFile file);
    }
}
Run Code Online (Sandbox Code Playgroud)

StudentController

[HttpGet]
public IActionResult Create()
{
    var student = new StudentCreateVM();
    student.Colleges = dbContext.Colleges.ToList();
    return View(student);
}

[HttpPost]
public IActionResult Create([FromForm] StudentCreateVM vm)
{
    Student student = new Student()
    {
        DisplayImage = vm.DisplayImage.FileName,
        Name = vm.Name,
        Roll_no = vm.Roll_no,
        CollegeId = vm.SelectedCollegeId,
    };


    if (ModelState.IsValid)
    {
        var fileName = fileService.Upload(vm.DisplayImage);
        student.DisplayImage = fileName;
        getpath = fileName;

        dbContext.Add(student);
        dbContext.SaveChanges();
        TempData["message"] = "Successfully Added";
    }
    return RedirectToAction("Index");
}
Run Code Online (Sandbox Code Playgroud)