在我们项目里经常会通过异步的方式加载大量的内容,以前的办法是通过后台拼接 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; } } }