在我们项目里经常会通过异步的方式加载大量的内容,以前的办法是通过后台拼接 Html 然后返回到前台,如果一个页面的数据量特别大的话用拼接 Html 的方式不仅降低了开发效率维护起来也特别麻烦。后来想到利用 Handlers 调用用户控件的方式动态的把执行结果返回。
办法是利用了 HttpServerUtility 类的 Execute 方法执行指定虚拟路径的处理程序。
我写了个 ViewWriter 类来封装:
/// <summary>
/// 加载页面视图并渲染。
/// </summary>
/// <typeparam name="T">需要渲染的页面实例。</typeparam>
public class ViewWriter<T> where T : Page
{
#region Fields...
/// <summary>
/// 声明页面对象实例。
/// </summary>
private Page _page;
#endregion
#region Constructors...
/// <summary>
/// 初始化 <see cref="ViewWriter"/> 类的新实例。
/// </summary>
public ViewWriter()
{
}
#endregion
#region Properties...
#endregion
#region Methods...
/// <summary>
/// 根据指定的虚拟路径从文件加载视图对象。
/// </summary>
/// <param name="path">控件文件的虚拟路径。</param>
/// <returns>返回指定类型的控件对象。</returns>
public T LoadViewControl(string path)
{
_page = new Page();
return (T)_page.LoadControl(path);
}
/// <summary>
/// 渲染视图。
/// </summary>
/// <param name="control">指定的泛型对象。</param>
/// <returns>返回执行结果。</returns>
public string RenderView(T control)
{
StringWriter output = new StringWriter();
_page.Controls.Add(control);
HttpContext.Current.Server.Execute(_page, output, false);
return output.ToString();
}
#endregion
}
Handler 的调用方法:
/// <summary>
/// Handler 的摘要说明
/// </summary>
public class UserControlHandler : IHttpHandler
{
#region Fields...
/// <summary>
/// 城市编号。
/// </summary>
private int cityId = 1;
/// <summary>
/// 城市名字。
/// </summary>
private string name = String.Empty;
/// <summary>
/// 分页索引。
/// </summary>
private int pageIndex = 0;
/// <summary>
/// 分页大小。
/// </summary>
private int pageSize = 10;
#endregion
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
ReceiveParam(context);
WriteControlHtml(context);
}
/// <summary>
/// 接收参数
/// </summary>
/// <param name="context"></param>
public void ReceiveParam(HttpContext context)
{
cityId = Int32.Parse(RequestUtil.GetQueryString("CityId"));
name = RequestUtil.GetQueryString("Name");
pageSize = Convert.ToInt32(RequestUtil.GetQueryString("PageSize"));
pageIndex = Convert.ToInt32(RequestUtil.GetQueryString("PageIndex"));
}
/// <summary>
/// 输出控件 Html 内容
/// </summary>
/// <param name="context"></param>
public void WriteControlHtml(HttpContext context)
{
ViewManager<UserControl> vm = new ViewManager<UserControl>();
var UserControl = vm.LoadViewControl("~/UserControls/UserControl.ascx");
UserControl.CityId = cityId;
UserControl.Name = name;
UserControl.PageIndex = pageIndex + 1;
UserControl.PageSize = pageSize;
string htmlStr = vm.RenderView(UserControl);
context.Response.Write(htmlStr);
}
public bool IsReusable
{
get
{
return false;
}
}
}