我的情况是:
我根据存储过程创建自定义报告,该存储过程返回三列(person_id [long],name [varchar(100)],age [int],photo [image])。这些是我的数据库表中的列和类型。
现在我正在为报告的每个图像使用这样的东西。
<img src="<%= Url.Action("ShowImage", "Reports", new {personId = result["PERSON_ID"]}) %>" />
ShowImage为
public virtual ActionResult ShowImage(long? personId)
{
try
{
if (personId.HasValue)
{
byte[] imageArray = StudentClient.GetPersonPhotoById(personId.Value);
if (imageArray == null)
return File(noPhotoArray, "image/jpg");
#region Validate that the uploaded picture is an image - temporary code
// Get Mime Type
byte[] buffer = new byte[256];
buffer = imageArray.Take(imageArray.Length >= 256 ? 256 : imageArray.Length).ToArray();
var mimeType = UrlmonMimeType.GetMimeType(buffer);
if (String.IsNullOrEmpty(mimeType) || mimeType.IndexOf("image") == -1)
return File(noPhotoArray, "image/jpg");
#endregion
return File(imageArray, "image/jpg");
}
}
catch
{
return File(noPhotoArray, "image/jpg");
}
}
我想使用某种替代方法,因为ShowImage()调用服务方法StudentClient.GetPersonPhotoById(personId.Value)这是非常有意义的。对于每一张图片,意味着分配对服务和DB的调用。
我想实际使用返回字节数组的照片列,而不是通过ShowImage控制器方法使用Person_id列。
这实际上会将对服务的调用次数减少为0并使用image列中的实际数据。这似乎非常简单,但我很难找到解决方案。
谢谢!
答案 0 :(得分:3)
最简单的解决方案 - 使用OutputCache。此外,您可以将缓存位置设置为客户端,浏览器将在下载后缓存图像。 VaryByParam将使您能够根据personId缓存图像。
答案 1 :(得分:0)
有一种非常巧妙的技术,您可以通过网络服务器将二进制数据直接从SQL Server流式传输到客户端。
这是我的代码:
public void StreamFile(Stream stream)
{
DbDataReader dr = LoadDbStream();
if (!dr.Read())
return;
const int BUFFERSIZE = 512;
byte[] Buffer = new byte[BUFFERSIZE];
long StartIndex = 0;
long Read = dr.GetBytes(0, StartIndex, Buffer, 0, BUFFERSIZE);
while (Read == BUFFERSIZE)
{
stream.Write(Buffer, 0, BUFFERSIZE);
StartIndex += BUFFERSIZE;
Read = dr.GetBytes(0, StartIndex, Buffer, 0, BUFFERSIZE);
}
stream.Write(Buffer, 0, (int)Read);
}
private DbDataReader LoadDbStream()
{
DbCommand cmd = Cms.Data.GetCommand("SELECT Data FROM CMS_Files WHERE FileId = @FileId", "@FileId", Id.ToString());
cmd.CommandType = System.Data.CommandType.Text;
cmd.Connection.Open();
return cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.CloseConnection);
}
命令对象是普通的命令对象。关键部分是CommandBehavior.SequentialAccess标志,因为这使得sql server只在你要求时发送数据。因此,您只能按查询中指定的顺序读取列。要做的另一点是流应该是来自请求和输出的输出流。切换输出缓冲。
将此与outputcaching结合使用,可以减少服务器上的内存负载。
西蒙
答案 2 :(得分:0)
您可以将其用作图像的来源。
src="data:image/jpg;base64,<%= System.Convert.ToBase64String(result["PHOTO"] as byte[]) %>"