簡體   English   中英

如何在 ASP.NET Core MVC 中顯示數據庫中的圖像?

[英]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屬性。

此外, ImageContentTypeImageSourceFileName屬性/列也不需要輸入元素。 您可以從上傳的文件中讀取此元信息。

[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>

正如我之前提到的,為您的創建視圖使用視圖模型並使用它是一個好主意。 此示例使用視圖模型將上傳的文件從瀏覽器傳輸到操作方法。

如何在asp.net core中上傳文件?

在視圖中,您應該為圖像輸入標簽分配如下名稱:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM