您可以将IFormFile 类型的新属性添加到您的视图模型
public class CreatePost
{
public string ImageCaption { set;get; }
public string ImageDescription { set;get; }
public IFormFile MyImage { set; get; }
}
在您的 GET 操作方法中,我们将创建此视图模型的对象并发送到视图。
public IActionResult Create()
{
return View(new CreatePost());
}
现在在我们的视图模型强类型化的创建视图中,有一个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>
以及处理表单发布的 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
}
如果您想将文件上传到应用程序中的某个目录,您应该使用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);
}
}
这会将文件保存到应用程序的wwwwroot 目录内的uploads 文件夹中,并使用Guids 生成随机文件名(以防止覆盖同名文件)
这里我们使用了一个非常简单的GetUniqueName 方法,它将从一个guid 中添加4 个字符到文件名的末尾,使其有点独特。您可以根据需要更新方法以使其更加复杂。
您应该将上传图片的完整网址存储在数据库中吗?
没有。不要将完整的 url 存储到数据库中的图像。如果明天您的企业决定将您的公司/产品名称从 www.thefacebook.com 更改为 www.facebook.com 怎么办?现在您必须修复表格中的所有网址!
你应该存储什么?
您应该存储上面生成的唯一文件名(我们在上面使用的uniqueFileName 变量)来存储文件名。当您想将图像显示回来时,您可以使用此值(文件名)并构建图像的 url。
例如,您可以在视图中执行此操作。
@{
var imgFileName = "cats_46df.png";
}
<img src="~/uploads/@imgFileName" alt="my img"/>
我刚刚将图像名称硬编码为imgFileName 变量并使用了它。但是您可以从数据库中读取存储的文件名并设置为您的视图模型属性并使用它。像
<img src="~/uploads/@Model.FileName" alt="my img"/>
将图像存储到表格中
如果你想将文件作为 bytearray/varbinary 保存到你的数据库,你可以像这样将 IFormFile 对象转换为字节数组
private byte[] GetByteArrayFromImage(IFormFile file)
{
using (var target = new MemoryStream())
{
file.CopyTo(target);
return target.ToArray();
}
}
现在在您的 http post action 方法中,您可以调用此方法从 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");
}