【原创】利用User Control与Control生成HTML
2012-08-14 16:40
162 查看
背景:我们在页面操作时,可能为了用户的体验使用了异步调用数据并且绑定,如果对于一些只需改变变量或是少量数据时,可以在异步服务器返回我们想要的数据,直接绑定到我们的页面,可是对于一些数据量比较大的数据,这些数据又包含Html代码等等时,我们就只能在异步服务器端进行字符串的拼接,然后返回,
例如:我们对于一个带分页功能的Repeater进行分页时,每点击下一页或是上一页时,要异步去请求需要的那一页数据,然后绑定在Repeater上。对于拼接字符串显然是又吃力又不是最优的解决方案。
最优解决方案:利用User Control与Control的某些方法直接生成HTML,然后返回给服务器,这样我们就不用拼接字符串了吧。
第一种方法:利用User Control生成HTML
这个方法是引用了老赵的文章,我只是给展示一下。
第一步,我们定义一个Comment类,内容如下:
第二步,为了显示一个评论列表,我们可以使用一个用户控件(ItemComments.ascx)来封装。自然,分页也是必不可少的:
后台方法:
第三步:我们在第二步中,要进行异步去请求服务器的数据,那个服务器页面是GetComments.ashx,那么我们就建立一个一般处理程序GetComments.ashx,代码如下:
这几行代码调用了关键代码,我们建立ViewManager类,类的内容如下:
上面有两个方法得关注一下:那就是:LoadViewControl和RenderView,LoadViewControl方法的作用是创建一个Control实例并返回,RenderView方法的作用则就是生成HTML了。
使用UserControl进行HTML代码生成是一个十分常用的技巧。尤其在AJAX应用越来越普及的情况下,合理使用上面提到的方式可以方便的为我们的应用添加AJAX效果。而且很多情况下,我们即使不需要在页面上显示内容,也可以将内容使用UserControl进行编辑。因为编写UserControl比拼接字符串的方式无论是在开发效率上还是可维护性上都高出许多。由于这个方式其实使用了WebForms这个久经考验的模型,因此在执行效率方面也是相当高的。此外,就刚才的例子来说,使用UserCotrol进行HTML生成还有其他好处:
页面呈现逻辑只实现了一次,提高了可维护性。
不会影响页面的SEO,因为在客户端<a />的href还是有效的。
事实上,WebForms是一个非常强大的模型,所以ASP.NET MVC的View也使用了WebForms的引擎。通过上面这个例子,我们其实还可以做到其他很多东西——例如用UserControl来生成XML数据,因为UserControl本身不会带来任何额外的内容。
第二种方法:利用Control生成HTML
这个方法是利用ajax来实现的。我们用上面的实例再利用Control生成HTML的方法再实现一次,废话也不多说了,直接上代码
第一步:建立WebForm页面 ViewItem.aspx,代码如下:
第二步:后台代码:
第三步:需要的Comment.cs类
这个方法最主要的是第二步中的RenderControl方法,它的作用是将服务器控件的内容输出到所提供的 System.Web.UI.HtmlTextWriter 对象中;
好了,两种方法说完了,根据自己的实际情况来选择使用哪个实现方式吧。
欢迎转载,原创地址: /article/5754252.html
例如:我们对于一个带分页功能的Repeater进行分页时,每点击下一页或是上一页时,要异步去请求需要的那一页数据,然后绑定在Repeater上。对于拼接字符串显然是又吃力又不是最优的解决方案。
最优解决方案:利用User Control与Control的某些方法直接生成HTML,然后返回给服务器,这样我们就不用拼接字符串了吧。
第一种方法:利用User Control生成HTML
这个方法是引用了老赵的文章,我只是给展示一下。
第一步,我们定义一个Comment类,内容如下:
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Collections.Generic; namespace UserControlToHtml { public partial class Comment { public DateTime CreateTime { get; set; } public string Content { get; set; } } public partial class Comment { private static List<Comment> s_comments = new List<Comment> { new Comment { CreateTime = DateTime.Parse("2007-1-1"), Content = "今天天气不错1" }, new Comment { CreateTime = DateTime.Parse("2007-1-2"), Content = "挺风和日丽的2" }, new Comment { CreateTime = DateTime.Parse("2007-1-3"), Content = "我们下午没有课3" }, new Comment { CreateTime = DateTime.Parse("2007-1-10"), Content = "这的确挺爽的4" }, new Comment { CreateTime = DateTime.Parse("2007-1-13"), Content = "我们下午没有课5" }, new Comment { CreateTime = DateTime.Parse("2007-1-10"), Content = "这的确挺爽的6" } }; public static List<Comment> GetComments(int pageSize, int pageIndex, out int totalCount) { totalCount = s_comments.Count; List<Comment> comments = new List<Comment>(pageSize); for (int i = pageSize * (pageIndex - 1); i < pageSize * pageIndex && i < s_comments.Count; i++) { comments.Add(s_comments[i]); } return comments; } } }
第二步,为了显示一个评论列表,我们可以使用一个用户控件(ItemComments.ascx)来封装。自然,分页也是必不可少的:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ItemComments.ascx.cs" Inherits="UserControlToHtml.ItemComments" %> <script src="jquery-1.5.1.min.js" type="text/javascript"></script> <script src="prototype.js" type="text/javascript"></script> <script type="text/javascript" language="javascript"> function getComments(pageIndex) { new Ajax.Updater( "comments", "/GetComments.ashx?page=" + pageIndex + "&t=" + new Date(), { method: "get" }); return false; // IE only } </script> <asp:Repeater runat="server" ID="rptComments"> <ItemTemplate> 时间:<%# (Container.DataItem as UserControlToHtml.Comment).CreateTime.ToString()%><br /> 内容:<%# (Container.DataItem as UserControlToHtml.Comment).Content%> </ItemTemplate> <SeparatorTemplate> <hr /> </SeparatorTemplate> <FooterTemplate> <hr /> </FooterTemplate> </asp:Repeater> <% if (this.PageIndex > 1) { %> <a href="#" title="上一页" onclick="return getComments(<%= this.PageIndex - 1 %>);">上一页</a> <% } %> <% if (this.PageIndex * this.PageSize < this.TotalCount) { %> <a href="#" title="上一页" onclick="return getComments(<%= this.PageIndex +1 %>);">下一页</a> <% } %>
后台方法:
protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); this.rptComments.DataSource = Comment.GetComments(this.PageSize, this.PageIndex, out this.m_totalCount); this.DataBind(); } public int PageIndex { get; set; } public int PageSize { get; set; } private int m_totalCount; public int TotalCount { get { return this.m_totalCount; } }
第三步:我们在第二步中,要进行异步去请求服务器的数据,那个服务器页面是GetComments.ashx,那么我们就建立一个一般处理程序GetComments.ashx,代码如下:
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; ViewManager<ItemComments> viewManager = new ViewManager<ItemComments>(); ItemComments control = viewManager.LoadViewControl("~/ItemComments.ascx"); control.PageIndex = Int32.Parse(context.Request.QueryString["page"]); control.PageSize = 3; context.Response.Write(viewManager.RenderView(control)); } public bool IsReusable { get { return false; } }
这几行代码调用了关键代码,我们建立ViewManager类,类的内容如下:
public class ViewManager<T> where T : UserControl { private Page m_pageHolder; //创建一个Control实例并返回 public T LoadViewControl(string path) { this.m_pageHolder = new Page(); return (T)this.m_pageHolder.LoadControl(path); } //就是生成HTML public string RenderView(T control) { StringWriter output = new StringWriter(); this.m_pageHolder.Controls.Add(control); HttpContext.Current.Server.Execute(this.m_pageHolder, output, false); return output.ToString(); } }
上面有两个方法得关注一下:那就是:LoadViewControl和RenderView,LoadViewControl方法的作用是创建一个Control实例并返回,RenderView方法的作用则就是生成HTML了。
使用UserControl进行HTML代码生成是一个十分常用的技巧。尤其在AJAX应用越来越普及的情况下,合理使用上面提到的方式可以方便的为我们的应用添加AJAX效果。而且很多情况下,我们即使不需要在页面上显示内容,也可以将内容使用UserControl进行编辑。因为编写UserControl比拼接字符串的方式无论是在开发效率上还是可维护性上都高出许多。由于这个方式其实使用了WebForms这个久经考验的模型,因此在执行效率方面也是相当高的。此外,就刚才的例子来说,使用UserCotrol进行HTML生成还有其他好处:
页面呈现逻辑只实现了一次,提高了可维护性。
不会影响页面的SEO,因为在客户端<a />的href还是有效的。
事实上,WebForms是一个非常强大的模型,所以ASP.NET MVC的View也使用了WebForms的引擎。通过上面这个例子,我们其实还可以做到其他很多东西——例如用UserControl来生成XML数据,因为UserControl本身不会带来任何额外的内容。
第二种方法:利用Control生成HTML
这个方法是利用ajax来实现的。我们用上面的实例再利用Control生成HTML的方法再实现一次,废话也不多说了,直接上代码
第一步:建立WebForm页面 ViewItem.aspx,代码如下:
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>RenderControlToHtml</title> <script src="jquery-1.5.1.min.js" type="text/javascript"></script> <script type="text/javascript" language="javascript"> function getComments(pageIndex) { $.ajax({ type: 'POST', url: "ViewItem.aspx", data: 'page=' + pageIndex, error: function() { alert('发生错误'); }, success: function(msg) { var total = "<%=TotalCount %>"; var pageSize = "<%=PageSize %>"; var pageContent = ""; if (pageIndex > 1) { pageContent = " <a href=\"#\" title=\"上一页\" onclick=\"return getComments(" + (pageIndex - 1) + ");\">上一页</a> "; } if (pageIndex * pageSize < total) { pageContent = pageContent + " <a href=\"#\" title=\"下一页\" onclick=\"return getComments(" + (pageIndex + 1) + ");\">下一页</a> "; } $("#comments").html(msg + pageContent); } }); return false; // IE only } </script> </head> <body> <form id="form1" runat="server"> <div id="comments"> <asp:Repeater runat="server" ID="rptComments"> <ItemTemplate> 时间:<%# (Container.DataItem as RenderControlToHtml.Comment).CreateTime.ToString()%><br /> 内容:<%# (Container.DataItem as RenderControlToHtml.Comment).Content%> </ItemTemplate> <SeparatorTemplate> <hr /> </SeparatorTemplate> <FooterTemplate> <hr /> </FooterTemplate> </asp:Repeater> <a href="#" title="上一页" onclick="return getComments(2);">下一页</a> </div> </form> </body> </html>
第二步:后台代码:
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { PageSize = 2; if (!string.IsNullOrEmpty(Request.Form["page"])) { this.rptComments.DataSource = Comment.GetComments(this.PageSize, int.Parse(Request.Form["page"]), out this.m_totalCount); this.DataBind(); Response.Write(RenderHtml(rptComments)); Response.End(); } else { this.rptComments.DataSource = Comment.GetComments(this.PageSize, 1, out this.m_totalCount); this.DataBind(); } } } protected int PageIndex { get { int result = 0; Int32.TryParse(this.Request.Form["page"], out result); return result > 0 ? result : 1; } } public int PageSize { get; set; } private int m_totalCount; public int TotalCount { get { return this.m_totalCount; } } /// <summary> /// 把一个控件的绑定数据生成一个html代码 /// </summary> /// <param name="Ctrl"></param> /// <returns></returns> private string RenderHtml(Control Ctrl) { StringBuilder sb = new StringBuilder(); StringWriter sw = new StringWriter(sb); HtmlTextWriter htw = new HtmlTextWriter(sw); Ctrl.RenderControl(htw); sw.Close(); htw.Close(); return sb.ToString(); } } }
第三步:需要的Comment.cs类
public partial class Comment { public DateTime CreateTime { get; set; } public string Content { get; set; } } public partial class Comment { private static List<Comment> s_comments = new List<Comment> { new Comment { CreateTime = DateTime.Parse("2007-1-1"), Content = "今天天气不错1" }, new Comment { CreateTime = DateTime.Parse("2007-1-2"), Content = "挺风和日丽的2" }, new Comment { CreateTime = DateTime.Parse("2007-1-3"), Content = "我们下午没有课3" }, new Comment { CreateTime = DateTime.Parse("2007-1-10"), Content = "这的确挺爽的4" }, new Comment { CreateTime = DateTime.Parse("2007-1-13"), Content = "我们下午没有课5" }, new Comment { CreateTime = DateTime.Parse("2007-1-10"), Content = "这的确挺爽的6" } }; public static List<Comment> GetComments(int pageSize, int pageIndex, out int totalCount) { totalCount = s_comments.Count; List<Comment> comments = new List<Comment>(pageSize); for (int i = pageSize * (pageIndex - 1); i < pageSize * pageIndex && i < s_comments.Count; i++) { comments.Add(s_comments[i]); } return comments; }
这个方法最主要的是第二步中的RenderControl方法,它的作用是将服务器控件的内容输出到所提供的 System.Web.UI.HtmlTextWriter 对象中;
好了,两种方法说完了,根据自己的实际情况来选择使用哪个实现方式吧。
欢迎转载,原创地址: /article/5754252.html
相关文章推荐
- (原创)利用扩展方法,给 IEnumerable<T> 增加一个生成 Html 的 select 标签的方法,不用 C# 中的反射技术
- (原创)利用扩展方法,给 IEnumerable<T> 增加一个生成 Html 的 CheckBox 标签的方法,不用 C# 中的反射技术
- 技巧:使用User Control做HTML生成 推荐
- 如何利用ASP.NET技术动态生成HTML页面
- 转:技巧:使用User Control做HTML生成
- 使用freemarker生成html、doc文件【原创】
- 【转】技巧:使用User Control做HTML生成
- WebApi中利用Razor模板引擎来生成html
- 利用ps生成html代码,如下图自己写css会不精确,可以利用ps生成
- 通过微软的HTML Help Workshop 利用.html文件 生成简单的chm帮助类的文件
- PHP实现html生成pdf、html生成图片 利用wkhtmltox,wkhtmltopdf扩展
- Url地址重写,利用HttpHander手工编译页面并按需生成静态HTML文件
- 利用phantomjs+selenium抓取fund.eastmoney.com/fund.html网站第二页js生成的页面
- 方案改进:直接通过User Control生成HTML
- 技巧:使用User Control做HTML生成(bs分销项目用到)
- 通过微软的HTML Help Workshop 利用.html文件 生成简单的chm帮助类的文件
- 利用Ajax生成ProgressBar:实现同类大批量数据批量生成Html,并实时显示进度条,可查看处理日志
- 技巧:使用User Control做HTML生成
- 如何利用ASP.NET技术动态生成HTML页面
- 【转帖】利用Java生成静态HTML页面