[英]How to display an image from the database in ASP.NET Core MVC?
我对 MVC Core 很陌生,并试图通过实体框架将图像添加到我的 SQL Server 数据库中。 我已经完成了数据库本身和视图。 我无法真正开始工作的是控制器。 有人能帮我把控制器安装到位吗? 请! 这是模型:
public class Product
{
[Key]
public int ProductID { get; set; }
[Required(ErrorMessage = "Please enter an product name")]
public string Name { get; set; }
[Required(ErrorMessage = "Please specify a category")]
public string Category { get; set; }
public string SubCategory { get; set; }
[Required(ErrorMessage = "Please enter a description")]
public string Description { get; set; }
[Required(ErrorMessage = "Please enter a positive price")]
public decimal Price { get; set; }
public byte[] Image { get; set; }
public string ImageSourceFileName { get; set; }
public string ImageContentType { get; set; }
}
这是数据库:
Product ID int False
Category nvarchar(MAX) False
Description nvarchar(MAX) False
Name nvarchar(MAX) False
Price decimal(18,2) False
SubCategory nvarchar(MAX) True
Image varbinary(MAX) True
ImageContentType nvarchar(MAX) True
ImageSourceFileName nvarchar(MAX) True
这是视图:
<div class="col-md-4">
<form asp-action="Create" method="post" enctype="multipart/
form-data" asp-controller="Products">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Image" class="control-label">File
input</label>
<input asp-for="Image" type="file"
aria-describedby="fileHelp" class="form-control-file" />
<span asp-validation-for="Image" class="text-danger"></span>
<small id="fileHelp" class="form-text text-muted">This is
some placeholder block-level help text for the above input. It's a bit
lighter and easily wraps to a new line.</small>
</div>
<div class="form-group">
<label asp-for="ImageSourceFileName"
class= "control-label"></label>
<input asp-for="ImageSourceFileName" class="form-control" />
<span asp-validation-for="ImageSourceFileName"
class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ImageContentType" class="control-label"></label>
<input asp-for="ImageContentType" class="form-control" />
<span asp-validation-for="ImageContentType"
class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
</div>
这是控制器:
public class ProductsController : Controller
{
private readonly ApplicationDbContext _context;
public ProductsController(ApplicationDbContext context)
{
_context = context;
}
// GET: Products
public async Task<IActionResult> Index()
{
return View(await _context.Products.ToListAsync());
}
// GET: Products/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var product = await _context.Products
.SingleOrDefaultAsync(m => m.ProductID == id);
if (product == null)
{
return NotFound();
}
return View(product);
}
// GET: Products/Create
public IActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create
([Bind("ProductID,Name,Category,SubCategory,
Description,Price,Image,ImageSourceFileName,ImageContentType")]
Product product)
{
if (ModelState.IsValid)
{
_context.Add(product);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(product);
}
// GET: Products/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var product = await _context.Products.SingleOrDefaultAsync(m =>
m.ProductID == id);
if (product == null)
{
return NotFound();
}
return View(product);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult>
Edit(int id,
[Bind
("ProductID,Name,Category,SubCategory,Description,Price,
Image,ImageSourceFileName,ImageContentType")]
Product product)
{
if (id != product.ProductID)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(product);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(product.ProductID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(product);
}
// GET: Products/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var product = await _context.Products
.SingleOrDefaultAsync(m => m.ProductID == id);
if (product == null)
{
return NotFound();
}
return View(product);
}
// POST: Products/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var product = await _context.Products.SingleOrDefaultAsync(m =>
m.ProductID == id);
_context.Products.Remove(product);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool ProductExists(int id)
{
return _context.Products.Any(e => e.ProductID == id);
}
}
我喜欢将图像存储在数据库中。 现在所有文本信息都很好地进入了数据库,但没有图像/字节......
图像应该在的索引视图中的空间是空的。
在 asp.net core 中,要将文件从浏览器发送到操作方法,您应该使用IFormFile
类型。
如果您不喜欢创建视图模型(我强烈建议您创建一个视图模型并使用它),您可以向IFormFile
类型的IFormFile
操作方法添加一个新参数,并将其转换为字节数组并将其存储在您的 Product 实体上的Image
属性。
此外, ImageContentType
和ImageSourceFileName
属性/列也不需要输入元素。 您可以从上传的文件中读取此元信息。
[HttpPost]
public IActionResult Create(Product model, IFormFile img)
{
if (img != null)
{
model.Image = GetByteArrayFromImage(img);
model.ImageSourceFileName = System.IO.Path.GetFileName(img.FileName);
model.ImageContentType = img.ContentType;
}
_context.Products.Add(model);
_context.SaveChanges();
return RedirectToAction("Index");
}
private byte[] GetByteArrayFromImage(IFormFile file)
{
using (var target = new MemoryStream())
{
file.CopyTo(target);
return target.ToArray();
}
}
现在确保您使用的文件输入元素与我们在表单中添加的新方法参数 ( img
) 同名。
<form asp-action="Create" method="post"
enctype="multipart/form-data" asp-controller="Product">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input asp-for="Name" />
<input asp-for="Category" />
<input asp-for="Price" />
<input type="file" name="img" />
<input type="submit" value="Create" class="btn" />
</form>
正如我之前提到的,为您的创建视图使用视图模型并使用它是一个好主意。 此示例使用视图模型将上传的文件从浏览器传输到操作方法。
在视图中,您应该为图像输入标签分配如下名称:
name="@Model.Image"
并在Controller中添加图片上传参数,并使用MemoryStream类将其转换为字节:
public virtual ActionResult yourController(Product prod, HttpPostedFileBase imgUpload)
{
Product prod = new Product();
var imgT = new MemoryStream();
if(imgUpload!=null){
imgUpload.InputStream.CopyTo(imgT);
prod.Image = imgT.ToArray();
}
}
希望能帮助到你!
这种方式让您可以将文件保存在文件夹中并保存数据库的路径
以下Entity
Dto 的代码
public string ImagePath { get; set; }
public IFormFile ImageFile { get; set; }
控制器的以下代码
var file = EntityDto.ImageFile;
if (file != null && file.Length > 0)
EntityDto.ImagePath = $"\\images\\folderName\\{EntityDto.Code}{Path.GetExtension(file.FileName)}";
if (AddAsync(EntityDto, $"{nameof(EntityDto)}."))
{
if (file != null && file.Length > 0)
{
var uploads = Path.Combine(_environment.WebRootPath, @"images\employees");
var filePath = Path.Combine(uploads, $"{EntityDto.Code}{Path.GetExtension(file.FileName)}");
using var fileStream = new FileStream(filePath, FileMode.Create);
await file.CopyToAsync(fileStream);
}
以下代码用于 UI
<form asp-action="New" method="post" enctype="multipart/form-data">
<input asp-for="@Model.EntityDto.ImageFile" type="file" />
</form>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.