Tip: Use user control for HTML generation)

Source: Internet
Author: User
Tags blank page

From: http://blog.zhaojie.me/2007/12/usercontrol-as-an-template.html

User Control is certainly not unfamiliar to everyone. In the process of using ASP. NET, except aspx pages, the most common is ascx. Ascx is a component with independent logic. It provides powerful reuse features and can be used properly, greatly improving development efficiency. Using user control to directly generate HTML content is already a common technique (especially in the Ajax era), but there is little content on the Internet, many people are still struggling to splice strings, so here I will briefly introduce this technique through an example.

Commenting on an object (article, image, music, etc.) is one of the most common features in applications. First, we define a comment class and the "get" Method Used in it:

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 = "good weather today"}, new comment {createtime = datetime. parse ("2007-1-2"), content = "awesome"}, new comment {createtime = datetime. parse ("2007-1-3"), content = "We have no classes in the afternoon"}, new comment {createtime = datetime. parse ("2007-1-1"), content = "This is really nice" }}; 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 ;}}

To display a comment list, we can use a user control (itemcomments. aspx) for encapsulation. Naturally, paging is also essential:

<Asp: repeater runat = "server" id = "rptcomments"> <itemtemplate> time: <% # (container. dataitem as comment ). createtime. tostring () %> <br/> content: <% # (container. dataitem as comment ). content %> </itemtemplate> <separatortemplate> <HR/> </separatortemplate> <footertemplate> <HR/> </footertemplate> </ASP: repeater> <% IF (this. pageindex> 1) {%> <a href = "/viewitem. aspx? Page = <% = This. pageindex-1%> "Title =" Previous Page "> previous page </a> & nbsp; <% }%> <% IF (this. pageindex * This. pagesize <this. totalcount) {%> <a href = "/viewitem. aspx? Page = <% = This. pageindex + 1%> "Title =" Previous Page "> next page </a> <%} %>

Also:

public partial class ItemComments : System.Web.UI.UserControl{    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;        }    }} 

Then use this component on the page (viewitem. aspx:

<div id="comments"><demo:ItemComments ID="itemComments" runat="server" /></div>

And:

public partial class ViewItem : System.Web.UI.Page{    protected void Page_Load(object sender, EventArgs e)    {        this.itemComments.PageIndex = this.PageIndex;    }     protected int PageIndex    {        get        {            int result = 0;            Int32.TryParse(this.Request.QueryString["page"], out result);             return result > 0 ? result : 1;        }    }} 

After viewitem. aspx is enabled, the effect is as follows:

Time: 0:00:00 content: Good weather today

Time: 0:00:00 content: Pretty elegant

Time: 0:00:00 content: We have no class in the afternoon

Next Page

The function of this page is very simple, that is, view comments. The page number of the current comment is specified using the page item of querystring, And the itemcomments. ascx control attributes are obtained and set in viewitem. aspx. The itemcomments control obtains and binds data based on its own attributes. The displayed content is all defined in ascx. Because the paging function is required, this comment control also contains links to the previous and next pages. The target of their links is the viewitem. ASPX page, and the query string of the page number is added.

The function has been completed, but I suddenly think it is inappropriate to use it. Why? Because the whole page is refreshed when we flip pages or when users post comments. This is not good. You may know that there are several other display parts on the viewitem page, but they remain unchanged. In addition, if several other parts need to be paged, the current page number of each part of the page may need to be retained. In this way, the development complexity is still relatively high.

So we should try Ajax. No matter whether a user views a comment, turning the page or posting a comment does not affect other content on the page. To develop this function, we naturally need server support. What should we do? Generally, we have two options:

  1. The server returns JSON data and presents it in the DOM of the client operation.
  2. The server directly returns the HTML content, and then sets the container on the client (for example, the DIV with the ID of comments above ).

However, no matter which method is used, the logic of "rendering" is generally written again (the first presentation logic is written in itemcomments. ascx ). If you use 1st methods, the rendering logic needs to be presented on the client through DOM operations; if you use 2nd methods, You Need To splice strings on the server. Either way violates the dry principle. When the rendering method in itemcomments. ascx is modified, the other one must be modified. In addition, it is difficult to maintain DOM elements or concatenated strings, and the development efficiency is naturally low.

How nice if we can get HTML content directly from the itemcomments control -- so let's do it. See the following code (getcomments. ashx ):

public class GetComments : IHttpHandler{    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 { ... }} 

Simple code, isn't it? Create an object, set properties, and output the data through response. Write. It's no big deal-but the key lies in the ViewManager class. Let's take a look at how it is implemented:

public class ViewManager<T> where T : UserControl{    private Page m_pageHolder;     public T LoadViewControl(string path)    {        this.m_pageHolder = new Page();        return (T)this.m_pageHolder.LoadControl(path);    }     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();    }}

ViewManager has only two methods: loadviewcontrol and renderview. The loadviewcontrol method creates a control instance and returns the result. The renderview method generates HTML. The trick of this implementation method is to use a new page object as the "Container" of the generated control. In the end, we actually run the entire lifecycle of the page object, and output the result. Because this blank page object does not produce any other code, we get the code generated by the user control.

However, to achieve this Ajax effect, two more things are required.

First, modify the page turning link in the itemcomments control to call a JavaScript function when it is clicked. For example, the Code of the previous page will become:

<A href = "/viewitem. aspx? Page = <% = This. pageindex-1%> "Title =" Previous Page "onclick =" Return getcomments (<% = This. pageindex-1%>); "> previous page </a>

The second is to implement the getcomments client method. Here I use the prototype framework. The advantage is that it can replace HTML Ajax with fairly concise code:

<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>

Success.

As mentioned earlier, using usercontrol to generate HTML code is a very common technique. Especially when Ajax applications become increasingly popular, the method mentioned above can be used properly to conveniently add Ajax effects to our applications. In many cases, you can use usercontrol to edit the content even if you do not need to display the content on the page. Because writing usercontrol is much higher than concatenating strings in both development efficiency and maintainability. Because this method actually uses the tested webforms model, the execution efficiency is also quite high. In addition, in the previous example, using usercotrol for HTML generation has other advantages:

  1. The page rendering logic is implemented only once, improving maintainability.
  2. Does not affect the SEO of the page, because the href on the client <A/> is still valid.

In fact, webforms is a very powerful model, so ASP. net mvc view also uses the webforms engine. Through the above example, we can actually do many other things-for example, using usercontrol to generate XML data, because usercontrol does not bring any additional content.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.