ASP.NET 中通过异步的方式调用用户控件

在我们项目里经常会通过异步的方式加载大量的内容,以前的办法是通过后台拼接 Html 然后返回到前台,如果一个页面的数据量特别大的话用拼接 Html 的方式不仅降低了开发效率维护起来也特别麻烦。后来想到利用 Handlers 调用用户控件的方式动态的把执行结果返回。

办法是利用了 HttpServerUtility 类的 Execute 方法执行指定虚拟路径的处理程序。

我写了个 ViewWriter 类来封装:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/// <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 的调用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/// <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;
        }
    }
}
posted @   Charles Zhang  阅读(868)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示