问题描述
如何使用带有一些模型数据的 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 中上传文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!