如何使用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>
我阅读了很多关于如何上传的教程,但是我没有看到上传的内容与上面的表格一样的数据。
此外,是否存在用于重新调整大小和图像水印的图像处理库,与Codeigniter图像处理类相同? (https://codeigniter.com/user_guide/libraries/image_lib.html
答案 0 :(得分:49)
您可以向视图模型中添加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);
}
}
这会将文件保存到应用程序uploads
目录下的wwwwroot
文件夹中,并使用Guids生成随机文件名(以防止覆盖同名文件)
这里我们使用一个非常简单的GetUniqueName
方法,它将guid中的4个字符添加到文件名的末尾,使其有点独特。您可以根据需要更新方法以使其更复杂。
您是否应该将完整的网址存储到数据库中的上传图片?
没有。不要将完整的URL存储到数据库中的映像中。如果明天您的公司决定将您的公司/产品名称从www.thefacebook.com
更改为www.facebook.com
,该怎么办?现在你必须修复表中的所有网址!
你应该存储什么?
您应该存储上面生成的唯一文件名(我们上面使用的uniqueFileName
varibale )来存储文件名。当您想要显示图像时,您可以使用此值(文件名)并为图像构建网址。
例如,您可以在视图中执行此操作。
@{
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");
}
答案 1 :(得分:2)
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;
}
}
IFileService
:
namespace studentapps.Services
{
public interface IFileService
{
string Upload(IFormFile file);
}
}
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");
}
答案 2 :(得分:0)
<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>
我的行动是
[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();
}
答案 3 :(得分:-1)
你可以尝试下面的代码
public class UploadImage
{
public string ImageFile { get; set; }
public string ImageName { get; set; }
public string ImageDescription { get; set; }
}
<form class="form-horizontal" asp-controller="Image" asp-action="UploadImage" method="POST" enctype="multipart/form-data">
<input type="file" asp-for="ImageFile">
<input type="text" asp-for="ImageName">
<input type="text" asp-for="ImageDescription">
</form>
public class Image
{
private IHostingEnvironment _hostingEnv;
public Image(IHostingEnvironment hostingEnv)
{
_hostingEnv = hostingEnv;
}
[HttpPost]
public async Task<IActionResult> UploadImage(UploadImage model, IFormFile ImageFile)
{
if (ModelState.IsValid)
{
var filename = ContentDispositionHeaderValue.Parse(ImageFile.ContentDisposition).FileName.Trim('"');
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images", ImageFile.FileName);
using (System.IO.Stream stream = new FileStream(path, FileMode.Create))
{
await ImageFile.CopyToAsync(stream);
}
model.ImageFile = filename;
_context.Add(model);
}
}
}