C# 在ASP.NET MVC中显示图像的不同方式以及何时使用哪种方法
我正在使用ASP.NET MVC4构建一个网站,以上载/显示图像,并找到了一些显示图像的方法,主要如下所示- 1)将图像作为文件本地存储在服务器上,并使用相对路径将其显示在页面上C# 在ASP.NET MVC中显示图像的不同方式以及何时使用哪种方法,c#,asp.net-mvc,asp.net-mvc-4,C#,Asp.net Mvc,Asp.net Mvc 4,我正在使用ASP.NET MVC4构建一个网站,以上载/显示图像,并找到了一些显示图像的方法,主要如下所示- 1)将图像作为文件本地存储在服务器上,并使用相对路径将其显示在页面上 //ImageFile is a property which holds a path to the image in the model <img src="@item.ImageFile" /> When the page is rendered, this becomes a path li
//ImageFile is a property which holds a path to the image in the model
<img src="@item.ImageFile" />
When the page is rendered, this becomes a path like - <img src="/Content/Images/Jellyfish.jpg" />
//控制器
public FileContentResult GetImg(int id)
{
byte[] byteArray = db.Photos.Find(id).Image;
if (byteArray != null)
{
return new FileContentResult(byteArray, "image/jpeg");
}
else
{
return null;
}
}
//视图(方法2)
@model IEnumerable
@foreach(模型中的var项目){
}
//视图(这是方法3)
@model IEnumerable
@foreach(模型中的var项目){
}
1)服务器端的处理将减少,因为函数调用将减少。如果您想要呈现动作的输出,您需要调用HTML助手方法HTML.RenderAction或HTML.action更多关于
2) 2和3之间的区别在于,当您直接输入字节数组时,您到服务器的往返次数较少(DNS查找等),但在单个请求中要下载的数据较多。有些浏览器可能会并行下载内容(每个域5-8次并行下载),因此如果使用3次,页面加载速度就会降低。更多关于paralel下载和
这让我们想到3)如果你有小图像,3是最好的选择,因为客户端会要求更少的资源,页面加载速度会更快,但是如果你有大图像,你应该使用1。我最近自己查阅了这篇文章,发现了微软的研究论文,其中比较了存储文件(如图像)的性能将数据库中的二进制数据转换为常规文件系统中的二进制数据 调查结果大致总结如下:
- 小文件(大小>256KB)最好作为字节数组存储在数据库中(第二个和第三个选项),从中可以快速检索并提供给用户
- 大型文件(大小>1MB左右)最好存储在文件系统中(您的第一个选择),因为大型数据库blob的吞吐量和碎片会随着大型文件而急剧恶化
- 在256KB和1MB之间(大致范围是模糊的,取决于您的精确设置),性能取决于文件可能被编辑或覆盖的次数;一般来说,数据库在处理静态文件时性能更好,而文件系统在处理频繁更改的文件时,在保持高吞吐量和低碎片方面性能更好
此外,这可能与您的具体情况无关,但通过单独的调用加载图像可以让您在这些操作中执行其他操作,如编写调试日志或在后台执行其他内务处理。我没有时间测试性能,但我会给您留下几点 在方法1中,您实际上只依赖HDD存储和性能来保存文件,并且依赖web服务器提供静态文件的能力 在方法2中,每次有请求时都会生成ByTestStream。。。存储和检索是DB驱动的(HDD当然起到了一定的作用),如果不添加一些相关代码(可能只是属性
OutputCache
,但它可能更复杂),就无法利用web服务器的本机缓存功能
在方法3中,客户端只是渲染,您将图像与网页一起发送。这里的性能确实取决于浏览器,但请记住,如果图像很大,则接收整个页面需要一些时间
所以我通常更喜欢方法1,我只需要在db中存储一个映像路径,然后我就可以从磁盘获取映像,并让IIS进行缓存、交付、优化等
选择方法2有很多正当的理由,主要是如果您有一个分布式web服务器体系结构,其中方法1意味着每个服务器都必须在HDD上保存一个映像副本,而将所有内容都放在DB中的一个位置意味着您可以随时检索IAMGE。。。可能需要实现一些缓存,以避免在每个请求中命中数据库
方法3实际上只适用于单次使用的小图像。我之所以说单次使用,是因为您不希望将其用于所有使用的图标和图像,它们应该保持静态,以便客户端可以缓存它们
希望这有助于做出更好的决定
在类似于2的场景中,使用多web服务器体系结构,在过去的工作中,我们使用了
//Directly re-construct the image in the view from the byte array (Image property of the model)
<img src="@String.Format("data:image/jpg;base64,{0}", Convert.ToBase64String(item.Image))" />
When the page is rendered, this becomes a path like - <img src="data:image/jpg;base64,/9j/4AAQSkZJRgABAgEA....<long string> .../>
public class Photo
{
public int ID { get; set; }
public string ImageFile { get; set; }
public byte[] Image { get; set; }
public string Caption { get; set; }
}
public FileContentResult GetImg(int id)
{
byte[] byteArray = db.Photos.Find(id).Image;
if (byteArray != null)
{
return new FileContentResult(byteArray, "image/jpeg");
}
else
{
return null;
}
}
@model IEnumerable<MyPhotoLibrary.Models.Photo>
@foreach (var item in Model) {
<tr>
<td>
<img src="@Url.Action("GetImg", "ViewPhotos", new { id = item.ID })" alt="Image" />
</td>
</tr>
}
@model IEnumerable<MyPhotoLibrary.Models.Photo>
@foreach (var item in Model) {
<tr>
<td>
<img src="@String.Format("data:image/jpg;base64,{0}", Convert.ToBase64String(item.Image))" />
</td>
</tr>
}