繁体   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