从数据库到 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");
}