从数据库到 IFormFile 从模型 class 中以字节为单位检索图像

Issue retrieving Image in bytes from Database to IFormFile from model class

在为我的 API 创建了一个 POST 方法后,我可以将图像上传到我将它们作为字节保存的数据库中,我想创建一个 GET 方法,它将请允许我获取他们的信息并最终在网页上显示他们。

我的模型 class 看起来像这样:

public class Image
{
    public int recipeId { get; set; }
    public string format { get; set; }
    public string description { get; set; }
    public IFormFile image { get; set; }
}

IFormFile image 是从前端上传并使用 MemoryStream 转换以填充数据库的图像,如下所示:

话虽这么说,下面是我的 GET 方法:

[Route("v1/recipe/image/{recipeId}")]
[HttpGet()]
public Image GetImage(int recipeId)
{
    using (var con = _connFactory())
    {
        con.Open();
        return con.Query<Image>("SELECT * FROM RecipeImage WHERE RecipeId = @recipeId", new { recipeId }).FirstOrDefault();
    }
}

但我收到以下错误:

System.Data.DataException: 'Error parsing column 3 (Image=System.Byte[] - Object)'

InvalidCastException: Unable to cast object of type 'System.Byte[]' to type 'Microsoft.AspNetCore.Http.IFormFile'.

我知道这里出了什么问题,但我找不到任何解决办法。我想到的唯一解决方案是为图像创建另一个模型 class 而不是 IFormFile 具有 byte[],但我想知道是否有更好的方法来解决这个问题。

那是因为您不能将 Byte 数组转换为 IFormFile

如果你想得到一个 Image 对象,你首先要将 Byte 数组加载到 MemoryStream 然后调用 Image.FromMemoryStream(stream)

using (var ms = new MemoryStream(byteArrayIn))
{
    return Image.FromStream(ms);
}

您可能需要考虑在 returns Image 类型的模型中添加一个额外的 属性,并在设置字节数组时将值加载到其中,即在内部setter 对应 byte[].

public class Image
{
    public int recipeId { get; set; }
    public string format { get; set; }
    public string description { get; set; }
    private byte[] _image { get; set; }
    public byte[] image { get { return _image; } set { 
        _image = value; 
        using(var ms = new MemoryStream(byteArrayIn)) ...
            imageFile = Image.FromStream(ms);...
    }
    public Image imageFile { get; set; }
}

一种方法是手动映射属性

using (var con = _connFactory())
{
    con.Open();
    return con.Query("SELECT * FROM RecipeImage WHERE RecipeId = @recipeId", new { recipeId })
                .Select(x => new Image() 
                {
                    recipeId = x.RecipeId,
                    format = x.Format,
                    description = x.Description,
                    image = new FormFile(new MemoryStream(x.Image), 0, x.Image.Length, null, "MyFile." + x.Format, "")
                })
                .FirstOrDefault();
}

但如果您想在 Web 上显示文件,您可能希望单独发送该文件。尝试导航到浏览器中的 v1/recipe/image/xxx 端点以查看图像是否加载。

[Route("v1/recipe/image/{recipeId}")]
[HttpGet()]
public async Task<IActionResult> GetImage(int recipeId)  
  {  
      var data = await con.QueryAsync<byte[]>("SELECT Image FROM RecipeImage WHERE RecipeId = @recipeId", new { recipeId }) 

      return File(new MemoryStream(data), "image/jpeg", "SomeName.jpg");  
  }