如何在 asp.net core 中上传文件?

How to upload files in asp.net core?(如何在 asp.net core 中上传文件?)
本文介绍了如何在 asp.net core 中上传文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How to upload files or images using Asp.net MVC 6 with some model data? Example, I have a form like this;

<form>
    <input type="file">
    <input type="text" placeholder="Image name...">
    <input type="text" placeholder="Image description...">
    <input type="submit" value="Submit">
</form>

我阅读了很多关于如何上传的教程,但我没有看到任何上传的数据,如上面的表格.

I read many Tutorials in how to upload but I don't see anything uploading with some data like the form above.

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

Also, is there any library for image manipulation for re-sizing and Image Watermarking same as Codeigniter image manipulation class? (https://codeigniter.com/user_guide/libraries/image_lib.html

推荐答案

您可以将 IFormFile 类型的新属性添加到您的视图模型中

You can add a new property of type IFormFile to your view model

public class CreatePost
{
   public string ImageCaption { set;get; }
   public string ImageDescription { set;get; }
   public IFormFile MyImage { set; get; }
}

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

and in your GET action method, we will create an object of this view model and send to the view.

public IActionResult Create()
{
   return View(new CreatePost());
}

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

Now in your Create view which is strongly typed to our view model, have a form tag which has the enctype attribute set to "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>

以及处理表单发布的 HttpPost 操作

And your HttpPost action to handle the form posting

[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
}

如果你想将文件上传到你应用中的某个目录,你应该使用 IHostingEnvironment 来获取 webroot 路径.这是一个工作示例.

If you want to upload the file to some directory in your app, you should use IHostingEnvironment to get the webroot path. Here is a working sample.

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);
    }
}

这会将文件保存到您应用的 wwwwroot 目录内的 uploads 文件夹,并使用 Guids 生成随机文件名(以防止覆盖同名文件)

This will save the file to uploads folder inside wwwwroot directory of your app with a random file name generated using Guids ( to prevent overwriting of files with same name)

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

Here we are using a very simple GetUniqueName method which will add 4 chars from a guid to the end of the file name to make it somewhat unique. You can update the method to make it more sophisticated as needed.

您应该将上传图片的完整网址存储在数据库中吗?

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

No. Do not store the full url to the image in the database. What if tomorrow your business decides to change your company/product name from www.thefacebook.com to www.facebook.com ? Now you have to fix all the urls in the table!

你应该存储什么?

您应该存储您在上面生成的唯一文件名(我们在上面使用的 uniqueFileName 变量)来存储文件名.当您想将图像显示回来时,您可以使用此值(文件名)并构建图像的 url.

You should store the unique filename which you generated above(the uniqueFileName varibale we used above) to store the file name. When you want to display the image back, you can use this value (the filename) and build the url to the image.

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

For example, you can do this in your view.

@{
    var imgFileName = "cats_46df.png";
}
<img src="~/uploads/@imgFileName"  alt="my img"/>

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

I just hardcoded an image name to imgFileName variable and used that. But you may read the stored file name from your database and set to your view model property and use that. Something like

<img src="~/uploads/@Model.FileName"  alt="my img"/>

将图像存储到表格中

如果要将文件作为 bytearray/varbinary 保存到数据库中,可以像这样将 IFormFile 对象转换为字节数组

If you want to save the file as bytearray/varbinary to your database, you may convert the IFormFile object to byte array like this

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

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

Now in your http post action method, you can call this method to generate the byte array from IFormFile and use that to save to your table. the below example is trying to save a Post entity object using entity framework.

[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");
}

这篇关于如何在 asp.net core 中上传文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)