在我们项目里经常会通过异步的方式加载大量的内容,以前的办法是通过后台拼接 Html 然后返回到前台,如果一个页面的数据量特别大的话用拼接 Html 的方式不仅降低了开发效率维护起来也特别麻烦。后来想到利用 Handlers 调用用户控件的方式动态的把执行结果返回。
办法是利用了 HttpServerUtility 类的 Execute 方法执行指定虚拟路径的处理程序。
我写了个 ViewWriter 类来封装:
1 /// <summary> 2 /// 加载页面视图并渲染。 3 /// </summary> 4 /// <typeparam name="T">需要渲染的页面实例。</typeparam> 5 public class ViewWriter<T> where T : Page 6 { 7 8 #region Fields... 9 10 /// <summary> 11 /// 声明页面对象实例。 12 /// </summary> 13 private Page _page; 14 15 #endregion 16 17 #region Constructors... 18 19 /// <summary> 20 /// 初始化 <see cref="ViewWriter"/> 类的新实例。 21 /// </summary> 22 public ViewWriter() 23 { 24 25 } 26 27 #endregion 28 29 #region Properties... 30 31 #endregion 32 33 #region Methods... 34 35 /// <summary> 36 /// 根据指定的虚拟路径从文件加载视图对象。 37 /// </summary> 38 /// <param name="path">控件文件的虚拟路径。</param> 39 /// <returns>返回指定类型的控件对象。</returns> 40 public T LoadViewControl(string path) 41 { 42 _page = new Page(); 43 return (T)_page.LoadControl(path); 44 } 45 46 /// <summary> 47 /// 渲染视图。 48 /// </summary> 49 /// <param name="control">指定的泛型对象。</param> 50 /// <returns>返回执行结果。</returns> 51 public string RenderView(T control) 52 { 53 StringWriter output = new StringWriter(); 54 55 _page.Controls.Add(control); 56 HttpContext.Current.Server.Execute(_page, output, false); 57 58 return output.ToString(); 59 } 60 61 #endregion 62 63 }
Handler 的调用方法:
1 /// <summary> 2 /// Handler 的摘要说明 3 /// </summary> 4 public class UserControlHandler : IHttpHandler 5 { 6 #region Fields... 7 8 /// <summary> 9 /// 城市编号。 10 /// </summary> 11 private int cityId = 1; 12 /// <summary> 13 /// 城市名字。 14 /// </summary> 15 private string name = String.Empty; 16 /// <summary> 17 /// 分页索引。 18 /// </summary> 19 private int pageIndex = 0; 20 /// <summary> 21 /// 分页大小。 22 /// </summary> 23 private int pageSize = 10; 24 25 #endregion 26 27 public void ProcessRequest(HttpContext context) 28 { 29 context.Response.ContentType = "text/plain"; 30 ReceiveParam(context); 31 WriteControlHtml(context); 32 } 33 34 /// <summary> 35 /// 接收参数 36 /// </summary> 37 /// <param name="context"></param> 38 public void ReceiveParam(HttpContext context) 39 { 40 cityId = Int32.Parse(RequestUtil.GetQueryString("CityId")); 41 name = RequestUtil.GetQueryString("Name"); 42 pageSize = Convert.ToInt32(RequestUtil.GetQueryString("PageSize")); 43 pageIndex = Convert.ToInt32(RequestUtil.GetQueryString("PageIndex")); 44 } 45 46 /// <summary> 47 /// 输出控件 Html 内容 48 /// </summary> 49 /// <param name="context"></param> 50 public void WriteControlHtml(HttpContext context) 51 { 52 ViewManager<UserControl> vm = new ViewManager<UserControl>(); 53 var UserControl = vm.LoadViewControl("~/UserControls/UserControl.ascx"); 54 UserControl.CityId = cityId; 55 UserControl.Name = name; 56 UserControl.PageIndex = pageIndex + 1; 57 UserControl.PageSize = pageSize; 58 59 string htmlStr = vm.RenderView(UserControl); 60 context.Response.Write(htmlStr); 61 } 62 63 public bool IsReusable 64 { 65 get 66 { 67 return false; 68 } 69 } 70 }