ASPNET MVC 生成静态页并显示生成进度
实现思路:
1.后台生成页面后,更新生成进度,写入缓存
2.前台用定时器读取缓存实时进度,更新进度条
页面效果:
MVCHelper.cs
#region 生成静态内容
/// <summary>
/// 生成静态内容
/// </summary>
/// <param name="context"></param>
/// <param name="viewPath"></param>
/// <param name="model"></param>
/// <returns></returns>
public static string RenderViewToString(ControllerContext context,
string viewPath,
object model = null)
{
ViewEngineResult viewEngineResult =
ViewEngines.Engines.FindView(context, viewPath, null);
if (viewEngineResult == null)
throw new FileNotFoundException("View" + viewPath + "cannot be found.");
var view = viewEngineResult.View;
context.Controller.ViewData.Model = model;
using (var sw = new StringWriter())
{
var ctx = new ViewContext(context, view,
context.Controller.ViewData,
context.Controller.TempData,
sw);
view.Render(ctx, sw);
return sw.ToString();
}
}
#endregion
MemcacheMgr.cs
using Enyim.Caching;
using Enyim.Caching.Configuration;
using Enyim.Caching.Memcached;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using ZSZ.IService;
namespace ZSZ.Website.Common
{
public class MemcacheMgr
{
private MemcachedClient client;
public static MemcacheMgr Instance { get; private set; }
static MemcacheMgr()
{
Instance = new MemcacheMgr();
}
private MemcacheMgr()
{
var settingService =
DependencyResolver.Current.GetService<ISettingService>();
string[] servers
= settingService.GetValue("MemCachedServers").Split(';');
MemcachedClientConfiguration config =
new MemcachedClientConfiguration();
foreach (var server in servers)
{
config.Servers.Add(new IPEndPoint(IPAddress.Parse(server), 11211));
}
config.Protocol = MemcachedProtocol.Binary;
client = new MemcachedClient(config);
}
public void SetValue(string key, object value, TimeSpan expires)
{
if (!value.GetType().IsSerializable)
{
throw new ArgumentException("value必须是可序列化的对象");
}
client.Store(StoreMode.Set, key, value, expires);
}
public T GetValue<T>(string key)
{
return client.Get<T>(key);
}
}
}
RebuildStaticPageResult.cs
[Serializable] public class RebuildStaticPageResult { /// <summary> /// 生成页面总数 /// </summary> public int TotleCount { get; set; } /// <summary> /// 已生成页面数量 /// </summary> public int RebuildCount { get; set; } /// <summary> /// 生成页面数量百分比 /// </summary> public string Percent { get; set; } }
HouseController.cs
#region 生成静态页
/// <summary>
/// 生成静态页
/// </summary>
/// <param name="houseId"></param>
private void CreateStaticPage(long houseId)
{
var house = houseService.GetDTOById(houseId);
var pics = housePicService.GetByHouseId(houseId);
var attachments = attachmentService.GetByHouseId(houseId);
var goodHouses = houseService.GetHousesByCommunityId((long)house.CommunityId, 3);
HouseIndexViewModel model = new HouseIndexViewModel();
model.House = house;
model.Pics = pics;
model.Attachments = attachments;
model.GoodHouses = goodHouses;
string html = MVCHelper.RenderViewToString(this.ControllerContext, @"~/Areas/WebAdmin/Views/House/StaticIndex.cshtml", model);
string houseDir = HttpContext.Server.MapPath("~/House/");
if (!Directory.Exists(houseDir))
{
Directory.CreateDirectory(houseDir);
}
System.IO.File.WriteAllText(houseDir + houseId + ".html", html);
Response.Write("<p>/House/" + houseId + ".html" + " " + house.CommunityName + house.Address + "</p>");
Response.Flush();
}
[HttpGet]
public ActionResult RebuildAllStaticPage()
{
//缓存key
ViewBag.Key = Guid.NewGuid().ToString();
return View();
}
[HttpPost]
public void RebuildAllStaticPageShow(string key)
{
Response.Write("====================== 生成静态页 begin ======================");
Response.Flush();
var houses = houseService.GetHouses();
//生成页面总数
int totleCount = houses.Count();
//已生成页面数量
int rebuildCount = 0;
string percent = "";
//缓存key
string cacheKey = "StaticPage_" + key;
foreach (var house in houses)
{
//生成静态页
CreateStaticPage(house.Id);
//已生成页面数量
rebuildCount++;
//计算百分比
percent = (((rebuildCount * 1.0) / totleCount) * 100).ToString("0") + "%";
//写入缓存
HttpContext.Cache.Insert(cacheKey, new RebuildStaticPageResult { TotleCount = totleCount, RebuildCount = rebuildCount, Percent = percent }, null, DateTime.Now.AddMinutes(3), TimeSpan.Zero);
// Website.Common.MemcacheMgr.Instance.SetValue(cacheKey, new RebuildStaticPageResult { TotleCount = totleCount, RebuildCount = rebuildCount, Percent = percent } , TimeSpan.FromMinutes(3));
}
Response.Write("====================== 生成静态页 end ======================");
Response.Flush();
}
/// <summary>
/// 生成进度
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
[HttpPost]
public ActionResult GetRebuildStaticPageProgress(string key)
{
string cacheKey = "StaticPage_" + key;
//读取缓存
RebuildStaticPageResult model = (RebuildStaticPageResult)HttpContext.Cache[cacheKey];
//RebuildStaticPageResult model = Website.Common.MemcacheMgr.Instance.GetValue<RebuildStaticPageResult>(cacheName);
if (model == null)
{
return Json(new RebuildStaticPageResult { TotleCount = 0, RebuildCount = 0, Percent = "0%" });
}
return Json(new RebuildStaticPageResult { TotleCount = model.TotleCount, RebuildCount = model.RebuildCount, Percent = model.Percent });
}
#endregion
RebuildAllStaticPage.cshtml
@*进度条*@
<div class="progressInfo">
<div class="progress"><div class="progress-bar"><span class="sr-only" style="width:0%"></span></div></div>
总共0页,已生成0页,生成进度:0%
</div>
<br />
<br />
@*生成页面详情*@
<iframe src="~/WebAdmin/House/RebuildAllStaticPageShow?key=@ViewBag.Key" width="80%" height="500"></iframe>
<script type="text/javascript">
$(function () {
//$.get("/WebAdmin/House/RebuildAllStaticPageShow", { key: '@ViewBag.Key' });
//定时器,每秒获取一次生成进度
var t1 = setInterval(getProgress, 1000);
function getProgress() {
$.post("/WebAdmin/House/GetRebuildStaticPageProgress", { key: '@ViewBag.Key' }, function (data) {
//更新进度
$(".progressInfo").html("<div class='progress'><div class='progress-bar'><span class='sr-only' style='width:" + data.percent + "'></span></div></div>总共" + data.totleCount + "页,已生成" + data.rebuildCount + "页,生成进度:" + data.percent);
//进度 100% ,停掉定时器
if (data.percent == "100%") {
//去掉定时器
clearInterval(t1);
}
});
};
});
</script>