我在ASP.NET MVC项目中使用名为Unite Gallery插件的图库插件,以显示存储在数据库中的图像。但是,同时加载所有图像需要很长时间(因为每张照片的大小为1MB-4MB,并且在页面加载时同时加载500张照片不是一个好主意)我认为必须有一个更好的方法即asenkron加载或部分加载。这是我的Razor和Controller代码。我查看了wweb和docs上的许多页面,但documentation页面中没有示例。你有什么主意吗?
<div id="gallery" style="display:none;">
@foreach (var item in Model)
{
if (item.FileData != null)
{
var base64 = Convert.ToBase64String(item.FileData);
var imgSrc = String.Format("data:image/gif;base64,{0}", base64);
<img alt='Image'
src="@imgSrc"
data-image="@imgSrc"
data-description='Image'>
}
}
</div>
<script type="text/javascript">
jQuery(document).ready(function () {
var gallery = jQuery("#gallery").unitegallery({
gallery_theme: "default" //theme skin
});
gallery.on("item_change", function (num, data) {
if((num%15) == 0)
{
$.ajax({
url: '@Url.Action("List", "PhotoContest")',
data: { isAll: isAllChecked, page: num }, //??? I pass the page parameter???
success: function(data){
//call is successfully completed and we got result in data
//??? NO IDEA ???
},
error:function (xhr, ajaxOptions, thrownError){
//some errror, some show err msg to user and log the error
alert(xhr.responseText);
}
});
}
});
});
</script>
public ActionResult List(string query)
{
var model = db.Photo.Select(m => new PhotoViewModel
{
Id = m.Id,
Name = m.Name,
StatusId = m.StatusId,
SubmitDate = m.SubmitDate,
FileAttachments = m.FileAttachments,
SubmitNo = m.SubmitNo
})
.ToArray();
return View("List", model);
}
更新
在尝试应用@Kris的完美方法后,我遇到了如下所示的错误。在网络上没有关于此特定问题的修复或解决方案。任何的想法?
页面加载后的图像会重载div和gallery边框,如下所示:
答案 0 :(得分:2)
一次加载30张图片
在Unite gallery中提供的Itemchange事件中加载剩余
主页
<div id="gallery" >
<input type="hidden" id="galleryPage" value="0"/>
@HTML.Action("GalleryImages") //first load 30 items as PageNo = 0
</div>
<script type="text/javascript">
var gallery;
jQuery(document).ready(function () {
gallery = jQuery("#gallery").unitegallery({
gallery_theme: "default" //theme skin
});
gallery.on("item_change", function (num, data) {
//when item loaded equals to 15 or 30 or multiples of 15 another 30 items get loaded
if((num%15) == 0)
{
$.ajax({
url: '@HTML.Action("GalleryImages")'+"?pageNo="+jQuery("galleryPage").val(),
data: { isAll: isAllChecked },
success: function(data){
jQuery("gallery").append(data);//partial view with new images
jQuery("galleryPage").val(gallery.getNumItems()/30); //page number total items/number of items per page
},
error:function (xhr, ajaxOptions, thrownError){
//some errror, some show err msg to user and log the error
alert(xhr.responseText);
}
});
}
});
});
</script>
部分视图(_galleryImages.cshtml)
@foreach (var item in Model)
{
if (item.FileData != null)
{
var base64 = Convert.ToBase64String(item.FileData);
var imgSrc = String.Format("data:image/gif;base64,{0}", base64);
<img alt='Image'
src="@imgSrc"
data-image="@imgSrc"
data-description='Image'>
}
}
控制器
//Main View
public ActionResult List()
{
return View();
}
//Partial View
public Action GalleryImages(int PageNo)
{
int PageSize = 30;
var model = db.Photo.Select(m => new PhotoViewModel
{
Id = m.Id,
Name = m.Name,
StatusId = m.StatusId,
SubmitDate = m.SubmitDate,
FileAttachments = m.FileAttachments,
SubmitNo = m.SubmitNo
}).Skip(PageNo*PageSize).Take(PageSize).ToArray();
return PartialView("_galleryImages", model);
}
答案 1 :(得分:1)
我认为这里只有一个问题。首先,无论你做什么,一次加载100张图像都会很慢。对于这一点,@ Kris可能有正确的想法。我不熟悉这个特定的库,但如果它提供了一种逐步加载少量图像的方法,那么你一定要使用它。
第二个问题是您使用的是base64编码的数据URI。以这种方式编码的图像大约是实际图像数据本身的150%。换句话说,你为已经紧张的情况增加了更大的压力。相反,您应该有一个返回图像数据的操作,如:
public ActionResult GetImage(int id)
{
var image = db.Images.Find(id);
if (image == null)
{
return new HttpNotFoundResult();
}
return File(image.FileData, image.FileType);
}
通过缓存数据库查询结果甚至整个响应,您可以在这里获得一些创意,但请注意,您需要大量的RAM,因为您将要存储大量的那里的图像数据。
第三,首先是使用数据库存储图像数据的问题。仅仅因为数据库提供blob类型,并不意味着你需要使用它。最高效的方法始终是直接从文件系统提供服务,因为IIS可以直接提供静态文件,而不涉及所有ASP.NET机制。不是将图像数据存储在数据库中,而是将图像写入文件系统位置,然后仅将图像的路径存储在数据库中。然后,您可以通过实际将所有图像卸载到CDN来进一步优化,确保超快速交付并从服务器上卸下几乎所有负载。