[英]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.