Spiga

技巧:使用User Control做HTML生成

2007-12-30 23:06 by Jeffrey Zhao, 13056 visits, 网摘, 编辑

  User Control大家肯定不会陌生,在使用ASP.NET的过程中,除了aspx页面,最常见的就莫过于ascx了。ascx是一个有独立逻辑的组件,提供了强大的复用特性,合理使用,能够大大提高开发效率。通过User Control直接生成HTML内容其实已经是一个比较常用的技巧了(尤其在AJAX时代),不过网络上这方面的内容比较少,很多人还是在苦苦地拼接字符串,因此在这里我通过一个实例简单介绍一下这个技巧。

  对一个对象(文章,图片,音乐,etc.)进行评论是应用中最常见的功能之一。首先,我们定义一个Comment类,以及其中会用到的“获取”方法:

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 = "今天天气不错"
        },
        new Comment
        {
            CreateTime = DateTime.Parse("2007-1-2"),
            Content = "挺风和日丽的"
        },
        new Comment
        {
            CreateTime = DateTime.Parse("2007-1-3"),
            Content = "我们下午没有课"
        },
        new Comment
        {
            CreateTime = DateTime.Parse("2007-1-1"),
            Content = "这的确挺爽的"
        }
    };
 
    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.aspx)来封装。自然,分页也是必不可少的:

<asp:Repeater runat="server" ID="rptComments">
    <ItemTemplate>
        时间:<%# (Container.DataItem as Comment).CreateTime.ToString() %><br />
        内容:<%# (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="上一页">上一页</a>&nbsp;
<% } %>

<% if (this.PageIndex * this.PageSize < this.TotalCount)
   { %>
        <a href="/ViewItem.aspx?page=<%= this.PageIndex + 1 %>" title="上一页">下一页</a>
<% } %>

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

  然后再页面(ViewItem.aspx)中使用这个组件:

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

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

  打开ViewItem.aspx之后效果如下:

时间:2007/1/1 0:00:00
内容:今天天气不错
时间:2007/1/2 0:00:00
内容:挺风和日丽的
时间:2007/1/3 0:00:00
内容:我们下午没有课
下一页

  这张页面的功能非常简单,那就是察看评论。当前评论的页码会使用QueryString的page项进行指定,然后在ViewItem.aspx里获取到并且设置ItemComments.ascx控件的属性。ItemComments控件会根据自身属性来获取数据,进行绑定,至于显示内容,全都定义在ascx中了。由于需要分页功能,这个评论控件中还包含了上一页和下一页的链接,他们链接的目标很简单,就是ViewItem.aspx页,并且加上页码的Query String而已。

  功能是完成了,不过用着用着忽然觉得不妥,为什么呢?因为我们在翻页,或者用户发布评论的时候,整张页面都刷新了。这可不好,要知道可能ViewItem页中还有其他几个显示部分,它们可是不变的。而且如果其他几个部分也需要分页,那么可能就需要保留页面上每一部分的当前页码,这样开发的复杂性还是比较高的。

  那么我们不如用AJAX吧。无论是用户察看评论时进行翻页还是发表评论,都不会对页面上的其他内容造成影响。要开发这个功能,自然需要服务器端的支持,那么该怎么做呢?一般我们总是有两种选择:

  1. 服务器端返回JSON数据,在客户端操作DOM进行呈现。
  2. 服务器端直接返回HTML内容,然后在客户端设置容器(例如上面id为comments的div)。

  不过无论采用哪种做法,“呈现”的逻辑一般总是另写一遍(第一次的呈现逻辑写在了ItemComments.ascx中)。如果使用第1种做法,那么呈现逻辑就需要在客户端通过操作DOM进行呈现;如果使用第2种做法,那么就要在服务器端进行字符串拼接。无论哪种做法都违背了DRY原则,当ItemComments.ascx里的呈现方式修改时,另一处也要跟着修改。而且无论是操作DOM元素还是拼接字符串维护起来都比较麻烦,开发效率自然也就不高了。

  如果我们能够直接从ItemComments控件获得HTML内容该多好啊——那么我们就这么做吧。请看如下代码(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 { ... }
} 

  很简单的代码,不是吗?创建对象,设置属性,然后通过Response.Write输出而已。实在没什么大不了的——不过关键就在于ViewManager类,我们来看一下它是怎么实现的:

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中只有两个方法:LoadViewControl和RenderView。LoadViewControl方法的作用是创建一个Control实例并返回,RenderView方法的作用则就是生成HTML了。这个实现方式的技巧在于使用了一个新建的Page对象作为生成控件的“容器”,而最后其实我们是将Page对象的整个生命周期运行一遍,并且将结果输出。由于这个空的Page对象不会产生任何其他代码,因此我们得到的,就是用户控件生成的代码了。

  不过要实现这个AJAX效果,还需要做两件事情。

  第一,就是简单修改一下ItemComments控件中的翻页链接,让它被点击时调用一个JavaScript函数。例如“上一页”的代码就会变成:

<a href="/ViewItem.aspx?page=<%= this.PageIndex - 1 %>" title="上一页"
    onclick="return getComments(<%= this.PageIndex - 1 %>);">上一页</a>

  第二,就是实现getComments这个客户端方法。在这里我使用了prototype框架,好处就是能够用相当简洁的代码来做到替换HTML的AJAX效果:

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

  大功告成。

  其实就像之前所说的那样,使用UserControl进行HTML代码生成是一个十分常用的技巧。尤其在AJAX应用越来越普及的情况下,合理使用上面提到的方式可以方便的为我们的应用添加AJAX效果。而且很多情况下,我们即使不需要在页面上显示内容,也可以将内容使用UserControl进行编辑。因为编写UserControl比拼接字符串的方式无论是在开发效率上还是可维护性上都高出许多。由于这个方式其实使用了WebForms这个久经考验的模型,因此在执行效率方面也是相当高的。此外,就刚才的例子来说,使用UserCotrol进行HTML生成还有其他好处:

  1. 页面呈现逻辑只实现了一次,提高了可维护性。
  2. 不会影响页面的SEO,因为在客户端<a />的href还是有效的。

  事实上,WebForms是一个非常强大的模型,所以ASP.NET MVC的View也使用了WebForms的引擎。通过上面这个例子,我们其实还可以做到其他很多东西——例如用UserControl来生成XML数据,因为UserControl本身不会带来任何额外的内容。

Add your comment

227 条回复

    评论共2页: 上一页 1 2 
  1. #201楼 YanziMyWife      2007-12-31 09:26
    怎么老赵的BLOG用MAXTHON2进会死掉啊!
      回复  引用  查看    
  2. #202楼 年华[未注册用户]2007-12-31 09:59
    好东西 以前也想过这样做,但是不知道用户控件怎样生成html代码,学习了

    感谢老赵!!!
      回复  引用    
  3. #203楼[楼主] Jeffrey Zhao      2007-12-31 10:05
    @怪怪
    我的这些容易写,呵呵。
      回复  引用  查看    
  4. #204楼[楼主] Jeffrey Zhao      2007-12-31 10:06
    @YanziMyWife
    是吗?有没有具体的症状?
      回复  引用  查看    
  5. #205楼 dusonchen[未注册用户]2007-12-31 10:13
    prototype,jquery,extjs三者,老赵你觉得哪个比较有优势呢?
      回复  引用    
  6. #206楼 winken21[未注册用户]2007-12-31 10:59
    过年了...
    一起床就看到好文章...
    哈哈...
    最近还正想用呢...
      回复  引用    
  7. #207楼 SZW      2007-12-31 11:13
    extjs太大了,只是效果比酷现成的功能多一点(像ASP.NET AJAX Toolkit那样),jquery属于“轻量级”的,完全自己开发的话我个人还是选择了jquery。不过要说和WebForm结合的好的话,当然还是Extjs,jquery在DOM操作上和WebForm的衔接让人不爽。

    老赵,"&t=" + new Date()在你这只是为了区分同一页面的不同URL字段,防止重新载入时不能刷新(就像有的验证码那样),还是有别的用途?
      回复  引用  查看    
  8. #208楼[楼主] Jeffrey Zhao      2007-12-31 11:39
    @SZW
    AJAX的GET操作可能会在IE下被缓存,用不同URL是为了避免这点。
      回复  引用  查看    
  9. #209楼 SZW      2007-12-31 11:41
    恩,我第一点就是这个意思,我做那些AJAX的验证码也只想到了这个方法,之前一直在寻找更好的办法,不过我用jquery做ajax的时候好像可以直接避免这个问题

    补充一点,有时候即使不是ajax的缓存,只是一个img/src之类的,也需要用这个方法去做,因为同样的URL浏览器是不会重新载入的,就像我们使用#name标签那样,不过就不只在AJAX范围内了
      回复  引用  查看    
  10. #210楼 Clingingboy      2007-12-31 11:44
    把标签头 If-Modified-Since设置为0就可以了,我直接手动改了prototype的代码加了一句
    Firefox没这个问题
      回复  引用  查看    
  11. #211楼 BlackCat      2007-12-31 12:02
    放假了,但是园子里依然热闹,支持一下
      回复  引用  查看    
  12. #212楼 隐姓埋名      2007-12-31 12:29
    才学初浅!
    似懂非懂!

    继续关注!!!

    谢谢!!!
      回复  引用  查看    
  13. #213楼 张荣华      2007-12-31 14:00
    学习中
    不过赵老大是不是在ViewItem.Page_Load中忘了赋值PageSize属性呢
      回复  引用  查看    
  14. #214楼 stonezhu      2007-12-31 14:11
    呵呵,赞一个,看来真是孤陋寡闻,老赵真有一套啊,这个方法不错。自己开发方便,又提高了UserControl的利用率,UserControl确实做得不错,生成不加垃圾代码,只是一个DIV,
    期待老赵多出经典

    祝 元旦快乐
      回复  引用  查看    
  15. #215楼[楼主] Jeffrey Zhao      2007-12-31 14:19
    @stonezhu
    哪来DIV啊,DIV是我在aspx里加的。
    UserControl一点多余代码也没有。
      回复  引用  查看    
  16. #216楼 stonezhu      2007-12-31 14:42
    @Jeffrey Zhao
    噢,刚才想到了Panel :)
    Panel加了后是一个DIV, UserControl是没有东西的,呵呵
    头晕了.2007的最后一次头晕:)
      回复  引用  查看    
  17. #217楼 金色海洋(jyk)      2007-12-31 15:56
    老大就是老大,这么多人回复。
      回复  引用  查看    
  18. #218楼 Awen7501[未注册用户]2007-12-31 16:11
    好文!希望园子里面这类型的文章多点,^_^,支持!
      回复  引用    
  19. #219楼 不明白[未注册用户]2007-12-31 17:39
    private static List<Comment> s_comments = new List<Comment>
    {
    new Comment
    {
    CreateTime = DateTime.Parse("2007-1-1"),
    Content = "今天天气不错"
    },
    ......
    };
    这是什么写法啊。怎么看不懂啊?
      回复  引用    
  20. #220楼 不明白[未注册用户]2007-12-31 17:46
    new表达式后面可以是{}??文章不错。就这个地方不明白。
      回复  引用    
  21. #221楼[楼主] Jeffrey Zhao      2007-12-31 19:03
    @不明白
    C#3.0的object initializer
      回复  引用  查看    
  22. #222楼 Melodicsoul      2007-12-31 21:27
    不错啊,又是另一种思路,有时间我也试下,感谢分享!
      回复  引用  查看    
  23. #223楼 HSimon[未注册用户]2008-01-01 01:08
    感谢分享。
    请问一下
    public class ViewManager<T> where T
    这种语法是什么,能推荐一些相关的资料么?

      回复  引用    
  24. #224楼[楼主] Jeffrey Zhao      2008-01-01 01:29
    @HSimon
    范型(Generic)。
    资料网上或MSDN一搜一大把,有点年份的东西了,需要跟进了,呵呵。:)
      回复  引用  查看    
  25. #225楼 啊东      2008-01-02 11:36
    多谢分享...
      回复  引用  查看    
  26. #226楼 doublog[未注册用户]2008-01-02 14:23
    这个和飞鸽写的哪个教程差不多 呵呵

    我一直用这种方法,但是我不知道这种方法效率如何?
    老赵 啥时候评测一下?
      回复  引用    
  27. #227楼[楼主] Jeffrey Zhao      2008-01-02 14:33
    @doublog
    性能和普通的ASP.NET WebForms一样。
      回复  引用  查看    
  28. #228楼 武眉博<活靶子.Net>      2008-01-02 15:25
    这个很好!我以前为了考虑SEO 先判断浏览器Agent如果是常见蜘蛛那么分页代码就/xx.pageindex.aspx 如果不是那就ajax的,今天又学习一招。
      回复  引用  查看    
  29. #229楼 doublog[未注册用户]2008-01-02 16:25
    --引用--------------------------------------------------
    武眉博&lt;活靶子.Net&gt;: 这个很好!我以前为了考虑SEO 先判断浏览器Agent如果是常见蜘蛛那么分页代码就/xx.pageindex.aspx 如果不是那就ajax的,今天又学习一招。
    --------------------------------------------------------
    你狠啊 看来为了蜘蛛什么都能想的出来啊
      回复  引用    
  30. #230楼 sunny11[未注册用户]2008-01-02 17:44
    请问一下,做大型社会网站,用ORM会存在性能问题吗,请问可以用ORM映射吗?
      回复  引用    
  31. #231楼 sunny11[未注册用户]2008-01-02 17:46
    网站和企业应用,关注点不一样,企业应用可能用,它关注的是业务,同时使用的人数也不会很多,但是大型网站可能访问量就很高,用ORM是不是就不好了
      回复  引用    
  32. #232楼[楼主] Jeffrey Zhao      2008-01-02 17:50
    --引用--------------------------------------------------
    doublog: --引用--------------------------------------------------
    武眉博&lt;活靶子.Net&gt;: 这个很好!我以前为了考虑SEO 先判断浏览器Agent如果是常见蜘蛛那么分页代码就/xx.pageindex.aspx 如果不是那就ajax的,今天又学习一招。
    --------------------------------------------------------
    你狠啊 看来为了蜘蛛什么都能想的出来啊
    --------------------------------------------------------
    会不会被搜索引擎判作弊?
      回复  引用  查看    
  33. #233楼[楼主] Jeffrey Zhao      2008-01-02 17:50
    @sunny11
    很难造成性能瓶颈。
      回复  引用  查看    
  34. #234楼 sunny11[未注册用户]2008-01-02 18:34
    很难造成性能瓶颈??
      回复  引用    
  35. #235楼 sunny11[未注册用户]2008-01-02 18:41
    用ORM效率是不高的
      回复  引用    
  36. #236楼[楼主] Jeffrey Zhao      2008-01-02 20:39
    @sunny11
    相对于许多东西都自己写,自然效率比较低,但是一个系统的性能问题不太会是ORM造成的。性能自有瓶颈,而这个瓶颈不太会是ORM。
      回复  引用  查看    
  37. #237楼 武眉博<活靶子.Net>      2008-01-02 20:45
    --引用--------------------------------------------------
    Jeffrey Zhao: --引用--------------------------------------------------
    doublog: --引用--------------------------------------------------
    武眉博&lt;活靶子.Net&gt;: 这个很好!我以前为了考虑SEO 先判断浏览器Agent如果是常见蜘蛛那么分页代码就/xx.pageindex.aspx 如果不是那就ajax的,今天又学习一招。
    --------------------------------------------------------
    你狠啊 看来为了蜘蛛什么都能想的出来啊
    --------------------------------------------------------
    会不会被搜索引擎判作弊?
    --------------------------------------------------------
    根据到目前的观察 并没有 而且我认为这个也不构成作弊 就像我用了ajax又要兼顾SEO在sitemap.aspx中给实际链接一样的
      回复  引用  查看    
  38. #238楼[楼主] Jeffrey Zhao      2008-01-02 20:54
    @武眉博<活靶子.Net>
    其实不一样的。理论上如果特意为搜索引擎“制作”和普通用户访问不同的页面,是会被认作作弊的。不过其实你这个应该还好,因为修改的地方不多。呵呵。
      回复  引用  查看    
  39. #239楼 小鹿      2008-01-02 22:23
    new Ajax.Updater(
    "comments",
    "/GetComments.ashx?page=" + pageIndex + "&t=" + new Date(),
    { method: "get" });
    Ajax.Updater是prototype里面的吗 不怎么明白
      回复  引用  查看    
  40. #240楼 1-2-3      2008-01-03 09:49
    非常实用。收藏。
      回复  引用  查看    
  41. #241楼[楼主] Jeffrey Zhao      2008-01-03 11:25
    @小鹿
    Ajax.Updater方法是prototype里的。
      回复  引用  查看    
  42. #242楼 HSimon[未注册用户]2008-01-03 16:51
    @Jeffrey Zhao
    谢谢!
    <T>这个知道,主要是后面那个“where T” 不是很理解。还希望说说
    :)
      回复  引用    
  43. #243楼[楼主] Jeffrey Zhao      2008-01-03 19:23
    --引用--------------------------------------------------
    HSimon: @Jeffrey Zhao
    谢谢!
    <T>这个知道,主要是后面那个“where T” 不是很理解。还希望说说
    :)
    --------------------------------------------------------
    泛型约束,具体查文档吧
      回复  引用  查看    
  44. #244楼 HSimon[未注册用户]2008-01-04 10:34
    @Jeffrey Zhao
    Thanks,:)
      回复  引用    
  45. #245楼 马可香蕉      2008-01-04 15:31
    HttpContext.Current.Server.Execute(this.m_pageHolder, output, false);

    方法第一个参数应该是IHttpHandler类型的,为什么Page类型也可以,Page继承IHttpHandler吗?
      回复  引用  查看    
  46. #246楼 SZW      2008-01-04 17:16
    @sunny11
    --引用--------------------------------------------------
    sunny11: 用ORM效率是不高的
    --------------------------------------------------------
    我在用.net3.5时候也一直也在考虑这个问题,不过看了一些测评,似乎这个“效率”高低的差别也只是在数据比较少的情况下表现得出来,数据很多的话ORM的效率就慢慢显现出来了,不过我没有亲自测试过,不知否有更可靠的数据。所以对大点的项目我还是比较“观望”ORM。

    如果那些测试结果是真实的,那这个问题也变得很辩证:小网站,不在乎细微的“效率”问题,ORM随便用;某些大网站,既然ORM可以提高开发效率,同时数据量大的时候ORM也不存在“降低效率”问题,还是可以考虑用。
      回复  引用  查看    
  47. #247楼 aaaa[未注册用户]2008-01-04 18:06
    代码有错
      回复  引用    
  48. #248楼 jas[未注册用户]2008-01-04 18:34
    多谢楼主好文! 我在做的时候,有一个问题, 我把viewmanager.cs 和GetComments 放在app_code folder里面, ItemComments.ascx在根目录下面,但是在getCommments里面的 Itemcomments却不能识别,所以编译出错。请帮助!
      回复  引用    
  49. #249楼 jun_brave[未注册用户]2008-01-04 19:50
    楼上说的跟我的情况差不多,不过我的搞笑点,有时候能通过,有时候报错,说找不到Itemcomments.......
    不清楚什么情况!
      回复  引用    
  50. #250楼 jun_brave[未注册用户]2008-01-04 19:53
    更正下,我那个错误是在GetComments.ashx中,就是不知道为什么有时候能通过,有时候就报错!!
    谢谢楼主的文章.........
      回复  引用    
  51. #251楼[楼主] Jeffrey Zhao      2008-01-05 01:15
    @jas
    用外部Class Library。
      回复  引用  查看    
  52. #252楼 静旅      2008-01-05 01:29
    老赵,怎么进这个页面,老是卡卡的。
    还说,这篇文章有没有源程序的。
      回复  引用  查看    
  53. #253楼 ll1[未注册用户]2008-01-05 02:57
    执行处理程序“System.Web.UI.Page”的子请求时出错

    HttpContext.Current.Server.Execute(this.m_pageHolder,output, false);

    在这里出现异常?望楼主指点!
      回复  引用    
  54. #254楼[楼主] Jeffrey Zhao      2008-01-05 09:39
    @ll1
    一模一样的代码吗?
      回复  引用  查看    
  55. #255楼[楼主] Jeffrey Zhao      2008-01-05 09:40
    @静旅
    所有的源代码都贴出来了阿。
      回复  引用  查看    
  56. #256楼 ll1[未注册用户]2008-01-05 11:19
    @Jeffrey Zhao
    代码基本相同,我只是把数据改成从数据库中取得,编译时有时能通过,有时报错,加断点就出现上面说的异常.
    在ashx文件中也是Itemcomments不能识别,不过有时候又能通过!
      回复  引用    
  57. #257楼 ll1[未注册用户]2008-01-05 11:20
    @Jeffrey Zhao
    忘记说了,我用的是2005的,应该没什么问题吧
      回复  引用    
  58. #258楼[楼主] Jeffrey Zhao      2008-01-05 11:51
    @ll1
    用外部引用Class Library吧,2005也没事的。
      回复  引用  查看    
  59. #259楼 ll1[未注册用户]2008-01-05 12:02
    @Jeffrey Zhao
    外部引用Class Library,应该如何做呢?
    我奇怪的是他为什么有时候能通过,有时候出错!
      回复  引用    
  60. #260楼 ll1[未注册用户]2008-01-05 20:48
    楼主,谢谢你的文章,我加了个using System.Web.UI;
    把Itemcomments直接改成UserControl后错误消失了!
      回复  引用    
  61. #261楼 ll1[未注册用户]2008-01-05 21:10
    @Jeffrey Zhao
    new Ajax.Updater(
    "comments",
    "/GetComments.ashx?page=" + pageIndex + "&t=" + new Date(),
    { method: "get" });
    这样的功能请问用JS直接实现能行么?
      回复  引用    
  62. #262楼 luyong[未注册用户]2008-01-05 22:43
    httpHandlers怎么加呢?
    我试了下
    <add verb="GET" path="GetComments.ashx" type="GetComments,MyUserControl"/>
    我是用vs2008建的asp.net web site,handler直接是使用你给的类,没做过修改,MyUserControl是工程的文件名,但还是出错:
    分析器错误信息: 未能加载文件或程序集“MyUserControl”或它的某一个依赖项。系统找不到指定的文件。
      回复  引用    
  63. #263楼 beyoung      2008-01-06 00:01
    protected override void OnPreRender(EventArgs e)
    {
    base.OnPreRender(e);

    this.rptComments.DataSource = Comment.GetComments(this.PageSize,this.PageIndex, out this.m_totalCount);
    this.DataBind();
    }

    中的这个rptComments是什么呢?怎么来的?
      回复  引用  查看    
  64. #264楼[楼主] Jeffrey Zhao      2008-01-06 01:19
    @luyong
    ashx是供直接调用的,不是用来配置的。
      回复  引用  查看    
  65. #265楼[楼主] Jeffrey Zhao      2008-01-06 01:19
    @beyoung
    ascx里有的。
      回复  引用  查看    
  66. #266楼 luyong[未注册用户]2008-01-06 11:38
    @Jeffrey Zhao
    谢谢
    另外,getComments(pageIndex)中return false; // IE only
    是不是要改为return true?
    另外运行点击下一页时,页面还是要重刷一下
    prototype中的Ajax.Updater中的"comments"是做什么用的?
      回复  引用    
  67. #267楼 luyong[未注册用户]2008-01-06 16:12
    哦,原来comments是用来容纳评论的div,忘了加了
    不过有点不爽,就是如果要用这个ascx,就需要在显示页面中加个div,id为comments

    如果直接把这个div放到usercontrol中,aspx就不依赖ascx了
    <div id="comments">
    <asp:Repeater ID="rptComment" runat="server">
    <ItemTemplate>
    时间:<%#(Container.DataItem as Comment).CreateTime.ToString() %>
    内容:<%#(Container.DataItem as Comment).Content.ToString() %>
    </ItemTemplate>
    <SeparatorTemplate>
    <hr />
    </SeparatorTemplate>
    <FooterTemplate>
    <hr />
    </FooterTemplate>
    </asp:Repeater>
    <a href="/MyUserControl/ViewItemPage.aspx?page=<%= this.PageIndex - 1 %>" title="上一页"
    onclick="return getComments(<%= this.PageIndex - 1 %>);">上一页</a> <a href="/MyUserControl/ViewItemPage.aspx?page=<%= this.PageIndex + 1 %>"
    title="下一页" onclick="return getComments(<%= this.PageIndex + 1 %>);">下一页</a>
    </div>
      回复  引用    
  68. #268楼 beyoung      2008-01-06 21:00
    关于OnPreRender的用法,MSDN中这样说:"通过查找文件数据或调用用户事件获取要呈现的广告信息。"
    我不是很明白,这个方法一般都用在什么地方,是什么意思呢?
    谢谢你的回复:)
      回复  引用  查看    
  69. #269楼[楼主] Jeffrey Zhao      2008-01-07 01:30
    @luyong
    看编程的概念吧。我这里把逻辑都放在aspx中,ascx只管呈现。
      回复  引用  查看    
  70. #270楼[楼主] Jeffrey Zhao      2008-01-07 01:31
    @beyoung
    其实……我也不知道。
    我只是知道每个生命周期的意义和执行顺序等等,然后在合时的地方使用它。
      回复  引用  查看    
  71. #271楼 feng173[未注册用户]2008-01-07 09:16
    我也是在这HttpContext.Current.Server.Execute(this.m_pageHolder, output, false);出错的
    后来我自己又重新建了一个aspx页面,在它的page_load里写了如下代码:
    TextBox tb = new TextBox();
    StringWriter output = new StringWriter();
    System.Web.UI.Page npage=new Page();

    npage.Controls.Add(tb);

    HttpContext.Current.Server.Execute(npage, output, false);
    Response.Write(output.ToString());
    这段代码在HttpContext.Current.Server.Execute(npage, output, false);这里也出错,实在没办法,望您指教
      回复  引用    
  72. #272楼 夕阳夕下      2008-01-07 16:55
    好帖,当然就要回帖,写得不错,收藏!
      回复  引用  查看    
  73. #273楼 jas[未注册用户]2008-01-07 17:57
    可不可以麻烦楼主把源码打个包,我想下载下来看一下。我的问题还是无法解决,谢谢
      回复  引用    
  74. #274楼 wade311[未注册用户]2008-01-07 18:12
    不知道楼主注意到当 ItemComments 中包含服务器控件时其在 m_pageHolder 中初始化时有问题
      回复  引用    
  75. #275楼 wade311[未注册用户]2008-01-07 18:52


    当在用户控件中不包含服务器控件时运行正常,但包含时总是报 " 执行处理程序“System.Web.UI.Page”的子请求时出错! ",页面显示错误为“ 类型“LinkButton”的控件“ctl00_LinkButton1”必须放在具有 runat=server 的窗体标记内 ”

    望楼主解惑,xiexie
      回复  引用    
  76. #276楼[楼主] Jeffrey Zhao      2008-01-08 00:46
    @wade311
    重写一个Page容器,覆盖掉一个VerifyXXX方法,具体查一下吧。
      回复  引用  查看    
  77. #277楼 ll1[未注册用户]2008-01-08 13:28
    @wade311
    你可以只在usercontrol中加datalist或者datarepeater,服务器端控件在这里面是不会报错的,其他不是放在datalist中的服务器控件你可以放到要显示这个usercontrol的aspx页中,那样操作也会更加简单
      回复  引用    
  78. #278楼 ll1[未注册用户]2008-01-08 13:32
    老赵啊,你的这个博客是不是中毒了?每次进来都要好长时间....
      回复  引用    
  79. #279楼 马可香蕉      2008-01-08 16:39
    问个问题:为什么我在HttpHandle里直接实例化UserControl比如

    UserControl u1 = new UserControl();
    u1.PageIndex = request....;
    u1.PageCount = request...;

    System.IO.StringWriter sw = new System.IO.StringWriter();
    System.Web.UI.HtmlTextWriter htw = new HtmlTextWriter(sw);

    u1.RenderControl(htw);

    context.Response.Write(sw.tostring());

    这样不行
      回复  引用  查看    
  80. #280楼[楼主] Jeffrey Zhao      2008-01-08 19:29
    @ll1
    不知道别人有这个问题吗?
      回复  引用  查看    
  81. #281楼[楼主] Jeffrey Zhao      2008-01-08 19:29
    @马可香蕉
    控件需要过生命周期
      回复  引用  查看    
  82. #282楼 Evi[未注册用户]2008-01-08 20:29
    UserControl里能不能放置TextBox和Button,然后通过点击Button提交表单呢?似乎不行。表单提交到了页面里去了。根本不会触发UserControl里Button的Click事件。如果我想提交表单该如何做?
      回复  引用    
  83. #283楼 Evi[未注册用户]2008-01-08 21:04
    @ll1
    @Jeffrey Zhao
    博客进来慢可能跟Window Live Message有关。每次进来时看到页面的内容下载完了。点击浏览器的"停止"就可以了。
      回复  引用    
  84. #284楼[楼主] Jeffrey Zhao      2008-01-08 22:12
    @Evi
    我的这个技巧只是用来生成HTML代码的。
    你的要求是需要动态加载控件了。在我这里搜索SwitchPartManager,可能对你有帮助。
      回复  引用  查看    
  85. #285楼 马可香蕉      2008-01-09 16:15
    @Jeffrey Zhao
    使它过生命周期是不是这行代码
    this.m_pageHolder.Controls.Add(control);

    但是这段代码是干嘛用的呢
    public T LoadViewControl(string path)
    {
    this.m_pageHolder = new Page();
    return (T)this.m_pageHolder.LoadControl(path);
    }

    为什么不直接执行Controls.Add,而要先Load进来
      回复  引用  查看    
  86. #286楼[楼主] Jeffrey Zhao      2008-01-09 17:31
    @马可香蕉
    Load里除了new还做了其他的事情。让他过生命周期是因为“Execute”。
      回复  引用  查看    
  87. #287楼 马可香蕉      2008-01-10 10:09
    @Jeffrey Zhao
    谢谢:)
    到底Load里还做了什么事情,我搜索了下没搜到什么东西
      回复  引用  查看    
  88. #288楼 guogu82      2008-01-14 17:12
    看完啦,眼睛疼。
      回复  引用  查看    
  89. #289楼 蓝天旭日      2008-01-16 10:40
    强人!
      回复  引用  查看    
  90. #290楼 Osamede      2008-01-16 15:25
    好文
      回复  引用  查看    
  91. #291楼 Cat Chen      2008-01-16 15:56
    说到底,ASPX在Jeffrey手上就是一个纯粹的模板引擎,哈哈。
      回复  引用  查看    
  92. #292楼[楼主] Jeffrey Zhao      2008-01-16 18:12
    @Cat Chen
    啥时也研究研究MVC的做法,hoho。
      回复  引用  查看    
  93. #293楼 Pandor Cai[未注册用户]2008-01-18 00:58
    public class ViewManager<T> where T : UserControl
    为什么不直接写
    public class ViewManager<UserControl>
      回复  引用    
  94. #294楼[楼主] Jeffrey Zhao      2008-01-18 01:45
    @Pandor Cai
    嗯?范型能这样使用吗?
      回复  引用  查看    
  95. #295楼 小庄      2008-01-21 08:50
    好办法!居然绕过了客户端的数据绑定!我打算把这个改成asp.net ajax的,真是谢谢!
      回复  引用  查看    
  96. #296楼 llinzzi[未注册用户]2008-01-26 15:21
    老赵这个方法很实用,受益匪浅。应该说颇为完美。
    优点是同一个ascx为ashx和aspx输出内容
    可这又让我联想到 在这里ascx我理解为了逻辑层,ashx和aspx作为了两种表现层,作为逻辑层提供出来的数据掺杂了html,不方便其他表现层应用程序调用。而且逻辑上不完美。
    如果把这里的ascx要做的事情放到webservice中,为aspx输出xml,为ajax输出json,似乎更完美写,也就是用ws事先所有逻辑。aspx制作数据格式化绑定并显示等。并可以给更多种形式的客户端提供便利。
    只不过客户端要进行dom操作了,比较麻烦。但理论上这种模式比较完美。
    以上的老赵肯定也想过。说起来简单,做起来很麻烦。就是想到哪说到哪,还请老赵见谅
      回复  引用    
  97. #297楼 pioman[未注册用户]2008-01-30 15:17
    代码看其来很优美
      回复  引用    
  98. #298楼 小兵a[未注册用户]2008-02-13 16:56
    做不出来
      回复  引用    
  99. #299楼 BAsil      2008-02-18 13:44
    请问赵哥在net 1.1有没有相应的解决方案?Server.Execute不支持IHttpHandler参数
      回复  引用  查看    
  100. #300楼[楼主] Jeffrey Zhao      2008-02-18 14:49
    @BAsil
    不好意思,我没有1.1的环境了。:(
      回复  引用  查看    
  101. #301楼 XL_ALEX[未注册用户]2008-02-21 09:29
    好。。正好我们要静态化页面。
      回复  引用    
  102. #302楼[楼主] Jeffrey Zhao      2008-02-21 10:02
    @XL_ALEX
    这和静态页无关
      回复  引用  查看    
  103. #303楼 zyug[未注册用户]2008-02-21 10:46
    说到底,ASPX在Jeffrey手上就是一个纯粹的模板引擎,哈哈。


    说的太精辟了
      回复  引用    
  104. #304楼 zyug[未注册用户]2008-02-21 14:13
    小弟有点不明白

    public class ViewManager<T> where T : UserControl

    完全可以在

    public class GetComments : IHttpHandler
    {
    public void ProcessRequest(HttpContext context)
    {
    Page p = new Page()
    Control c = p.LoadControl(path);
    //设置c属性并添加
    p.AddControl(c);

    System.IO.StringWrier sw = new ....
    context.Current.Server.Execute(..);
    Response.Write (sw.ToString());
    //


    }
    }


    这样对新手更利于理解.为何要多用一个 范围类呢


    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();
    }
    }

    对此不是很理解,望能赐教
      回复  引用    
  105. #305楼[楼主] Jeffrey Zhao      2008-02-21 14:33
    @zyug
    一个辅助类啊
      回复  引用  查看    
  106. #306楼 WOW玩家      2008-03-03 11:42
    这个方法好。我以前是用一个空的aspx页面+用户控件来生成html 进行ajax交互的。这个比我的先进。
      回复  引用  查看    
  107. #307楼 flyboy[未注册用户]2008-03-04 22:13
    为什么不直接把用户控件放到updatepanel中去呢?这样多省事啊
      回复  引用    
  108. #308楼[楼主] Jeffrey Zhao      2008-03-04 22:39
    @flyboy
    一是性能问题。
    二是开发人员接受程度问题。
    所以我们没有用UpdatePanel。
      回复  引用  查看    
  109. #309楼 flyboy[未注册用户]2008-03-12 08:19
    --引用--------------------------------------------------
    Jeffrey Zhao: @flyboy
    一是性能问题。
    二是开发人员接受程度问题。
    所以我们没有用UpdatePanel。
    --------------------------------------------------------

    知道了,谢谢老赵
      回复  引用    
  110. #310楼 flyboy[未注册用户]2008-03-12 22:43
    Public Class ViewManager
    Inherits UserControl
    Private m_pageHolder As Page
    Public Function RenderView(ByVal path As String) As String
    Dim output As New System.IO.StringWriter
    m_pageHolder = New Page
    'Dim wControl As Control = m_pageHolder.LoadControl(path)
    m_pageHolder.Controls.Add(m_pageHolder.LoadControl(path))
    HttpContext.Current.Server.Execute(m_pageHolder, output, False)
    Return output.ToString
    End Function
    End Class

    如果我在user control 放置 服务器控件就出现下面的错误

    类型“TextBox”的控件“ctl00_TextBox1”必须放在具有 runat=server 的窗体标记内。

    老赵帮帮忙,或者能不能把您的工程传上来吗?因为我C#不是很熟。
      回复  引用    
  111. #311楼 flyboy[未注册用户]2008-03-13 00:42
    to Jeffrey Zhao

    我已经把你的代码原封不动的实现了一遍,c#中没问题。

    不过有一个问题

    我在输入

    ItemComments control = viewManager.LoadViewControl("~/ItemComments.ascx");
    的时候 ItemComments 不能出来智能提示。我在vb中这样定义就报错。
    也就是说在其他类中不能定义 ItemComments

    为什么啊???郁闷,今天搞了一天了,太晚了明天再搞,
      回复  引用    
  112. #312楼 flyboy[未注册用户]2008-03-13 08:13
    今天早上测试了一下
    如果在您的文件中加个服务器控件,也会报同样的错误,(<hr />
    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> 是我添加的内容,但是我发现您添加的 <asp:Repeater runat="server" ID="rptComments"> 为什么就不报错呢??我再看看)
    “/WebSite1”应用程序中的服务器错误。
    --------------------------------------------------------------------------------

    类型“TextBox”的控件“ctl00_TextBox1”必须放在具有 runat=server 的窗体标记内。



    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="ItemComments.ascx.cs" Inherits="ItemComments" %>
    <asp:Repeater runat="server" ID="rptComments">
    <ItemTemplate>
    时间:<%# (Container.DataItem as Comment).CreateTime.ToString() %><br />
    内容:<%# (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="上一页"
    onclick="return getComments(<%= this.PageIndex - 1 %>);">上一页</a>
    <% } %>

    <% if (this.PageIndex * this.PageSize < this.TotalCount)
    { %>
    <a href="ViewItem.aspx?page=<%= this.PageIndex + 1 %>" title="上一页" onclick="return getComments(<%= this.PageIndex + 1 %>);" >下一页</a>
    <% } %>


    <hr />
    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
      回复  引用    
  113. #313楼 flyboy[未注册用户]2008-03-13 08:23
    真是奇怪我测试了就是 Repeater ListView控件可以用,其他控件都会报错。
    老赵您在写DEMO时,有没有遇到同样的问题?有没有直接的办法或者变通的办法,因为我要用服务器端控件主要是想使用ajax toolkits
      回复  引用    
  114. #314楼[楼主] Jeffrey Zhao      2008-03-14 16:27
    @flyboy
    写一个新的Page类,把它的VerifyXXX方法override掉(留空即可),用它作为容器。
      回复  引用  查看    
  115. #315楼[楼主] Jeffrey Zhao      2008-03-28 10:43
    @swing
    这个技术本就不适合使用AJAX Control Toolkit,赫赫。
    遇到问题具体问题具体分析就可以了。
      回复  引用  查看    
  116. #316楼 凯凯[未注册用户]2008-03-30 11:59
    new Comment
    {
    CreateTime = DateTime.Parse("2007-1-1"),
    Content = "今天天气不错"
    },
    new Comment
    {
    CreateTime = DateTime.Parse("2007-1-2"),
    Content = "挺风和日丽的"
    },
    new Comment
    {
    CreateTime = DateTime.Parse("2007-1-3"),
    Content = "我们下午没有课"
    },
    new Comment
    {
    CreateTime = DateTime.Parse("2007-1-1"),
    Content = "这的确挺爽的"
    }
    这段怎么老提示有错误啊
      回复  引用    
  117. #317楼[楼主] Jeffrey Zhao      2008-03-30 14:55
    @凯凯
    这是C# 3.0的特性。
      回复  引用  查看    
  118. #318楼 帝之晓      2008-04-03 10:14
    天那,评论那么长
      回复  引用  查看    
  119. #319楼 mclkyo[未注册用户]2008-04-15 09:27
    我还是没法找到那个用户控件的类
    不知道楼主能否详细讲一下怎么得到那个类,谢谢
      回复  引用    
  120. #320楼[楼主] Jeffrey Zhao      2008-04-15 10:09
    @mclkyo
    直接LoadControl就可以了阿,Cast成ascx.cs里的那个类。
      回复  引用  查看    
  121. #321楼 mclkyo[未注册用户]2008-04-15 16:41
    问题是在我的代码里面找不到ItemComments这个类
    也就是LoadControl后无法进行Cast啊
    就是ItemComments control = viewManager.LoadViewControl("~/ItemComments.ascx");这句代码,说无法识别ItemComments这个类
    所以也就无法对PageIndex,PageSize这个变量赋值啊
    请楼主解答,谢谢
      回复  引用    
  122. #322楼[楼主] Jeffrey Zhao      2008-04-16 00:34
    @mclkyo
    你的ItemComments.ascx.cs里写的是什么类阿?
      回复  引用  查看    
  123. #323楼 mclkyo[未注册用户]2008-04-16 08:59
    我用的是VS2005,用添加选项添加的UserControl的
    生成的代码为
    public partial class ItemComments : System.Web.UI.UserControl
    {
    }
    不知道为什么,在别的项面就是无法找到ItemComments这个类,奇怪了??
      回复  引用    
  124. #324楼[楼主] Jeffrey Zhao      2008-04-16 11:00
    @mclkyo
    别的项目?命名空间正确了没?
      回复  引用  查看    
  125. #325楼 mclkyo[未注册用户]2008-04-16 12:03
    项目,命名空间都没问题
    我发现在aspx.cs文件中要识别ItemComments这个类就必须在Aspx页面加上<%@ Register src=''%>头
    但在我如果要在AppCode的类里面引用ItemComments这个类就不知道怎么做了
      回复  引用    
  126. #326楼[楼主] Jeffrey Zhao      2008-04-16 20:47
    @mclkyo
    App_Code没有引用WebSite里的项目,自然无法使用。
    这段代码不能写在App_Code里。
      回复  引用  查看    
  127. #327楼 希望回答[未注册用户]2008-04-27 11:09
    麻烦问下 我的用户控件和ashx文件不是放在同一目录下
    ControlManager<HeadControl> viewManager = new ControlManager<HeadControl>();
    HeadControl control = viewManager.LoadViewControl("Controls/HeadControl.ascx");
    无法编译通过,用命名控件组织也不可以。想问下怎么解决。
    谢谢。。。。
      回复  引用    
  128. #328楼[楼主] Jeffrey Zhao      2008-04-27 14:37
    @希望回答
    放在额外的Class Library里。
      回复  引用  查看    
  129. #329楼 zys1202[未注册用户]2008-05-07 13:44
    ControlManager<HeadControl> viewManager = new ControlManager<HeadControl>();
    HeadControl control = viewManager.LoadViewControl("Controls/HeadControl.ascx");
    无法编译通过,用命名控件组织也不可以。想问下怎么解决。
    找不到命名空间或类型名称 HeadControl
      回复  引用    
  130. #330楼[楼主] Jeffrey Zhao      2008-05-07 15:03
    HeadControl定义在什么地方?
      回复  引用  查看    
  131. #331楼 五味果      2008-05-23 15:38
    老赵,你能把这个例子能提供下载或者给我邮箱发一份吗
    我的邮箱:taibaizhou@163.com
    我在调试你的例子时候遇到,
    ViewManager<ItemComments> viewManager = new ViewManager<ItemComments>();
    ItemComments control = viewManager.LoadViewControl("ItemComments.ascx");
    ItemComments类不能识别出来。
    麻烦你了!
      回复  引用  查看    
  132. #332楼 jim.chb[未注册用户]2008-06-01 23:25
    老赵,首先谢谢您的无私贡献哦!我在调试的时候遇到这个问题:执行到
    HttpContext.Current.Server.Execute(this.m_pageHolder, output, false);

    这里的时候,报错:

    Error executing child request for handler 'System.Web.UI.Page'.

    老赵能给点思路么,多谢!
      回复  引用    
  133. #333楼 jim.chb[未注册用户]2008-06-01 23:28
    其中的 output变量已经取出usercontrol的html字符串了 ,但就不能return呢?
      回复  引用    
  134. #334楼[楼主] Jeffrey Zhao      2008-06-02 00:10
    @jim.chb
    执行时出现异常?我的例子你能运行吗?
      回复  引用  查看    
  135. #335楼 r[未注册用户]2008-06-04 17:23
    看了,凑个数
      回复  引用    
  136. #336楼 qinii[未注册用户]2008-06-04 19:53
    晕了。总算找到了。。。。。。。。。。。
    还是去年写的,郁闷~~~~一直认为可以这样实现,只怪本人对asp.net还深入学习,没办法自己实现。。。

      回复  引用    
  137. #337楼 iceflying[未注册用户]2008-06-05 15:29
    老赵 我无法在ashx 中访问你的ItemComments 类
    是不是还要using什么东西,怎么调用外部的class lib啊 谢谢阿

    using System;
    using System.Web;
    using System.Web.UI;

    public class CallUC : IHttpHandler {

    public void ProcessRequest (HttpContext context) {
    context.Response.ContentType = "text/plain";

    ViewManager<ItemComments> viewManager = new ViewManager<ItemComments>();
    UserControl control = viewManager.LoadViewControl("~/testControl.ascx");
    control.
    control.PageIndex = Int32.Parse(context.Request.QueryString["page"]);
    control.PageSize = 3;

    context.Response.Write(viewManager.RenderView(control));
    }

    public bool IsReusable {
    get {
    return false;
    }
    }

    }
      回复  引用    
  138. #338楼 beafhorse[未注册用户]2008-06-10 12:42
    能不能把这个东西和web service结合起来?
      回复  引用    
  139. #339楼 beafhorse[未注册用户]2008-06-11 00:12
    还有个问题.如果UserControl里面也有javascript代码,这些代码会正常实现么?我测试了一下,似乎不行.
      回复  引用    
  140. #340楼[楼主] Jeffrey Zhao      2008-06-11 00:23
    --引用--------------------------------------------------
    beafhorse: 还有个问题.如果UserControl里面也有javascript代码,这些代码会正常实现么?我测试了一下,似乎不行.
    --------------------------------------------------------
    肯定不行的
      回复  引用  查看    
  141. #341楼 beafhorse[未注册用户]2008-06-11 14:33
    --引用--------------------------------------------------
    Jeffrey Zhao: --引用--------------------------------------------------
    beafhorse: 还有个问题.如果UserControl里面也有javascript代码,这些代码会正常实现么?我测试了一下,似乎不行.
    --------------------------------------------------------
    肯定不行的
    --------------------------------------------------------
    那如果UserControl中必须放入一些js代码的话,本文讲的这个方法是不是就不适用了?
      回复  引用    
  142. #342楼[楼主] Jeffrey Zhao      2008-06-11 16:08
    @beafhorse
    在这个基础上做点补充阿。
      回复  引用  查看    
  143. #343楼 beafhorse[未注册用户]2008-06-11 17:32
    --引用--------------------------------------------------
    Jeffrey Zhao: @beafhorse
    在这个基础上做点补充阿。
    --------------------------------------------------------
    如何做,给点提示吧.
      回复  引用    
  144. #344楼 Eve[未注册用户]2008-06-13 04:50
    --引用--------------------------------------------------
    Jeffrey Zhao: --引用--------------------------------------------------
    beafhorse: 还有个问题.如果UserControl里面也有javascript代码,这些代码会正常实现么?我测试了一下,似乎不行.
    --------------------------------------------------------
    肯定不行的
    --------------------------------------------------------
    “UserControl里面也有javascript代码,这些代码会正常实现么?”指的是什么?
    又为什么肯定不行?
    我试了一下似乎都能运行啊?
      回复  引用    
  145. #345楼[楼主] Jeffrey Zhao      2008-06-13 10:34
    --引用--------------------------------------------------
    “UserControl里面也有javascript代码,这些代码会正常实现么?”指的是什么?
    又为什么肯定不行?
    我试了一下似乎都能运行啊?
    --------------------------------------------------------
    不可能的,你是在用我这种设置innerHTML的方式更新吗?
      回复  引用  查看    
  146. #346楼 beafhorse[未注册用户]2008-06-13 10:40
    --引用--------------------------------------------------
    Jeffrey Zhao: --引用--------------------------------------------------
    “UserControl里面也有javascript代码,这些代码会正常实现么?”指的是什么?
    又为什么肯定不行?
    我试了一下似乎都能运行啊?
    --------------------------------------------------------
    不可能的,你是在用我这种设置innerHTML的方式更新吗?
    --------------------------------------------------------
    那以何种方式更新可以让UserControl中的javascript代码正常执行呢?困惑了两天了.
      回复  引用    
  147. #347楼 beafhorse[未注册用户]2008-06-13 11:23
    昨天看老赵的asp.net ajax教程,有了思路.
    把usercontrol里面的script代码提取出来.放在页面的head中解析.

    这样是否可行?还有更好的办法没?
      回复  引用    
  148. #348楼 beafhorse[未注册用户]2008-06-13 11:31
    如果只考虑ie,加个defer就可以了.firefox有没有类似的标签?

      回复  引用    
  149. #349楼 Sam Lin      2008-06-13 18:51
    看了颇久代码,在把代码copy在vs2005 C#中,怎么老是出错~~~
    原来是C#3.0的新特性~啊,看来要开始学习3.0了
    好象从2.0到3.0新加的东西,大多是从javascript中拿过来的
    比如匿名、委托、还有刚才的创建对象……

    另外想问一下:
    通过这种url重写,把所有的aspx都重写成html
    实际上只是一种伪地址,真正访问的时候也还是aspx页面,这种做能提高搜索引擎收录率吗?还有应该不会对网站的性能有所提高吧?
      回复  引用  查看    
  150. #350楼 Eve[未注册用户]2008-06-13 19:39
    @ Jeffrey Zhao
    --引用--------------------------------------------------
    不可能的,你是在用我这种设置innerHTML的方式更新吗?
    --------------------------------------------------------
    我用的jQuery的html(),不知道它是不是innerHTML方式。

    我的代码:
    <script src="js/jquery-1.2.3.pack.js" type="text/javascript"></script>
    <script type="text/javascript">
    function getComments(pageIndex)
    {
    $.ajax({
    url: "GetComments.ashx?page=" + pageIndex + "&t=" + new Date(),
    type: "get",
    success: function(msg) {
    $("#comments").html(msg);

    }
    });

    }
    </script>
    这段代码直接放在UserControl里也可以运行的。
      回复  引用    
  151. #351楼[楼主] Jeffrey Zhao      2008-06-14 01:49
    --引用--------------------------------------------------
    beafhorse: 昨天看老赵的asp.net ajax教程,有了思路.
    把usercontrol里面的script代码提取出来.放在页面的head中解析.

    这样是否可行?还有更好的办法没?
    --------------------------------------------------------
    则就是标准的做法了吧,当然不一定要放在head里,eval一下就行。
      回复  引用  查看    
  152. #352楼[楼主] Jeffrey Zhao      2008-06-14 01:49
    --引用--------------------------------------------------
    beafhorse: 如果只考虑ie,加个defer就可以了.firefox有没有类似的标签?
    --------------------------------------------------------
    defer是标准,可惜firefox不支持
      回复  引用  查看    
  153. #353楼[楼主] Jeffrey Zhao      2008-06-14 01:50
    --引用--------------------------------------------------
    Sam Lin: 看了颇久代码,在把代码copy在vs2005 C#中,怎么老是出错~~~
    原来是C#3.0的新特性~啊,看来要开始学习3.0了
    好象从2.0到3.0新加的东西,大多是从javascript中拿过来的
    比如匿名、委托、还有刚才的创建对象……

    另外想问一下:
    通过这种url重写,把所有的aspx都重写成html
    实际上只是一种伪地址,真正访问的时候也还是aspx页面,这种做能提高搜索引擎收录率吗?还有应该不会对网站的性能有所提高吧?
    --------------------------------------------------------
    其实新特性是参考动态语言的,不一定是JavaScript。
    至于url重写,把aspx写成html不会造成多大差别,也不会提高性能。
      回复  引用  查看    
  154. #354楼[楼主] Jeffrey Zhao      2008-06-14 01:51
    --引用--------------------------------------------------
    Eve: @ Jeffrey Zhao
    我用的jQuery的html(),不知道它是不是innerHTML方式。

    我的代码:
    &lt;script src=&quot;js/jquery-1.2.3.pack.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
    function getComments(pageIndex)
    {
    $.ajax({
    url: &quot;GetComments.ashx?page=&quot; + pageIndex + &quot;&amp;t=&quot; + new Date(),
    type: &quot;get&quot;,
    success: function(msg) {
    $(&quot;#comments&quot;).html(msg);

    }
    });

    }
    &lt;/script&gt;
    这段代码直接放在UserControl里也可以运行的。
    --------------------------------------------------------
    jquery自动提取script代码后eval,并设置innerHTML
      回复  引用  查看    
  155. #355楼 brightwang      2008-06-17 22:39
    我的做法是专门建个页面,然后把要输出的内容如(repeater)放在页面上,把body、html等无关的元素都去掉,然后代码绑定就可以直接输出到客户端,不知道你认为这中方式如何。
      回复  引用  查看    
  156. #356楼[楼主] Jeffrey Zhao      2008-06-17 23:14
    --引用--------------------------------------------------
    brightwang: 我的做法是专门建个页面,然后把要输出的内容如(repeater)放在页面上,把body、html等无关的元素都去掉,然后代码绑定就可以直接输出到客户端,不知道你认为这中方式如何。
    --------------------------------------------------------
    效果一样
      回复  引用  查看    
  157. #357楼 beafhorse[未注册用户]2008-06-24 15:07
    --引用--------------------------------------------------
    希望回答: 麻烦问下 我的用户控件和ashx文件不是放在同一目录下
    ControlManager&lt;HeadControl&gt; viewManager = new ControlManager&lt;HeadControl&gt;();
    HeadControl control = viewManager.LoadViewControl(&quot;Controls/HeadControl.ascx&quot;);
    无法编译通过,用命名控件组织也不可以。想问下怎么解决。
    谢谢。。。。
    --------------------------------------------------------
    同样的问题.
    如何才能让ashx找到usercontrol的那个类?
    您上面提到了调用外部类.如何调用?给点提示吧.
    如果都改成ViewManager<UserControl> viewManager = new ViewManager<UserControl>(); 虽然可以编译通过,但是使用起来很不方便.无法传值给ItemComment .
      回复  引用    
  158. #358楼 tsgtx[未注册用户]2008-07-03 08:03
    为什么不能用rendercontrol将用户控件转换成html串呢?
    别人已经做好的用户控件,我要怎么做才能把它转换成html串呢?
      回复  引用    
  159. #359楼 tsgtx[未注册用户]2008-07-03 08:04
    为什么不能用rendercontrol将TabContainer及其它包含的控制转换成html串呢?
      回复  引用    
  160. #360楼 willieQ      2008-07-07 16:08
    website时,怎么定位用户控件类?
    ----对应代码--------
    ViewManager<ItemComments> viewManager = new ViewManager<ItemComments>();
    ======================

    我的用户控件类是
    uc_WebUserControl
    路径是/uc/

    我直接写成----
    ViewManager<uc_WebUserControl> viewManager = new ViewManager<uc_WebUserControl>();

    不行
      回复  引用  查看    
  161. #361楼 代码乱了      2008-07-13 23:05
    这个方法很不错,很实用
      回复  引用  查看    
  162. #362楼 singleblue      2008-07-14 08:53
    这边的m_pageHolder,如果用Control来代替,效率是否能高一点点?
      回复  引用  查看    
  163. #363楼[楼主] Jeffrey Zhao      2008-07-14 09:38
    @singleblue
    没法用Control的。
      回复  引用  查看    
  164. #364楼 matta[未注册用户]2008-07-14 16:44
    其实比较贴切的说,是指你的
    HttpContext.Current.Server.Execute(this.m_pageHolder, output, false);

    其实不用这样的开销.
      回复  引用    
  165. #365楼[楼主] Jeffrey Zhao      2008-07-14 16:53
    @matta
    没看出有什么问题来
      回复  引用  查看    
  166. #366楼 matta[未注册用户]2008-07-14 17:06
    一定要这样才行吗,没有更优的了?
    HttpContext.Current.Server.Execute(this.m_pageHolder, output, false);
      回复  引用    
  167. #367楼[楼主] Jeffrey Zhao      2008-07-14 20:25
    @matta
    不说优不优,没有觉得这个东西哪里差了阿,呵呵。
      回复  引用  查看    
  168. #368楼 clefoo      2008-07-15 01:02
    protected void Page_Load(object sender, EventArgs e)
    {
    StringWriter output = new StringWriter();
    top s=(top)this.LoadControl("top.ascx");
    this.Controls.Add(s);
    HttpContext.Current.Server.Execute(this, output, false);
    Response.Write(output.ToString());
    }

    HttpContext.Current.Server.Execute(this, output, false);
    这句是不是可以省略不要了(top是UserControl)
      回复  引用  查看    
  169. #369楼[楼主] Jeffrey Zhao      2008-07-15 01:09
    @clefoo
    没看懂,你这个东西是做什么用的?
      回复  引用  查看    
  170. #370楼 clefoo      2008-07-15 08:59
    @Jeffrey Zhao
    就是你的那个事例改了下。

    userControl生成html
      回复  引用  查看    
  171. #371楼[楼主] Jeffrey Zhao      2008-07-15 11:51
    @clefoo
    能运行么?
      回复  引用  查看    
  172. #372楼 miao~      2008-07-15 12:06
    有个问题,为什么我做的时候 点下一页的时候 如果
    <a href="/ViewItem.aspx?page=<%= this.PageIndex - 1 %>" title="上一页"
    onclick="return getComments(<%= this.PageIndex - 1 %>);">上一页</a>

    就不会执行 onclick 而是直接 跳转到 ViewItem.aspx?page=2

    而要是把 href="javascript:void(0)" 就可以执行 onclick 了....

    prototype 不熟..用 Jquery 改了下

    function getComments(pageIndex)
    {
    $.get("GetComments.ashx",{page:pageIndex,t:new Date()},function(data){$("#comments").html(data)});
    }

    不知道其他的朋友有没有类似的问题?
      回复  引用  查看    
  173. #373楼 clefoo      2008-07-15 12:49
    @miao~
    在href是要加上void(0);

    @Jeffrey Zhao
    可以运行
      回复  引用  查看    
  174. #374楼 miao~      2008-07-15 13:10
    @clefoo
    但是老赵那个href 没有加 void(0) 啊....
    怎么能让它只执行 onClick 而保留 href 里的并不跳转呢?
      回复  引用  查看    
  175. #375楼[楼主] Jeffrey Zhao      2008-07-15 13:13
    @miao~
    看我的js是怎么写的
      回复  引用  查看    
  176. #376楼 miao~      2008-07-15 13:20
    @Jeffrey Zhao
    非常感谢,少加了
    return false; // IE only


      回复  引用  查看    
  177. #377楼 陈招展      2008-07-17 00:33
    这么多评论啊…
      回复  引用  查看    
  178. #378楼 Fanty      2008-07-21 12:57
    ViewManager里面事实上是存在有一个BUG.如果控件存在着LinkButton,GridView等的必须依赖Form存在的控件,就会出现报错现象!
    我的解决方法是
    /// <summary>
    /// 解释控件HTML
    /// </summary>
    /// <param name="control"></param>
    /// <returns></returns>
    public string RenderView(T control)
    {
    try
    {
    HtmlForm _form = new HtmlForm();
    _form.ID = "form1";
    _form.EnableViewState = false;
    _pageHolder.Controls.Add(_form);
    HtmlGenericControl _ulControl = new HtmlGenericControl("UL");
    _form.Controls.Add(_ulControl);
    _ulControl.Controls.Add(control);
    System.IO.StringWriter output = new System.IO.StringWriter();
    System.Web.HttpContext.Current.Server.Execute(_pageHolder, output, false);
    System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
    xmlDoc.LoadXml(output.ToString());
    _pageHolder.Controls.Clear();
    output.Close();
    _form.Dispose();

    return xmlDoc.DocumentElement.SelectNodes("UL")[0].InnerXml;
    }
    catch { return string.Empty; }
    }
    至于为什么要用XmlDocument读取指定的HTML模板,就是要去除生成出来多余的HTML代码
      回复  引用  查看    
  179. #379楼[楼主] Jeffrey Zhao      2008-07-21 14:01
    @Fanty
    不是bug,上面的评论就讲过解决方法,你这个做法太复杂了。
      回复  引用  查看    
  180. #380楼 Fanty      2008-07-21 19:28
    @Jeffrey Zhao
    对不起,我没有看见上面的哪有更好的解决方案!
    不过您当时的这种做法给了我很大的构想!令我可以想到2008 MVC下去进行该模式的设计!并且省下要建立ashx的麻烦
      回复  引用  查看    
  181. #381楼[楼主] Jeffrey Zhao      2008-07-21 21:46
    @Fanty
    不直接使用Page,而是使用Page的自定义子类,把VerifyXxxx方法给override掉即可。
      回复  引用  查看    
  182. #382楼 淡淡的[未注册用户]2008-08-28 15:04
    程序发出来了,楼主,福利大家
      回复  引用    
  183. #383楼 淡淡的[未注册用户]2008-08-28 15:05
    楼主多做视频呀。哇哇
      回复  引用    
  184. #384楼 tc11o8      2008-09-11 18:05
    老赵,你能把这个例子能提供下载或者给我邮箱发一份吗
    我的邮箱:zmj119@hotmail.com
      回复  引用  查看    
  185. #385楼 窜天下[未注册用户]2008-09-15 09:40
    这段代码是什么意思:


    List<Comment> comments = new List<Comment>(pageSize);

    for (int i = pageSize * (pageIndex - 1);
    i < pageSize * pageIndex && i < s_comments.Count; i++)


    List<Comment> comments = new List<Comment>(pageSize);这句代码的pageSize传进去干嘛,给谁啊,没属性也没字段的。
    谢谢zhao,麻烦解释一下,我运行不了

      回复  引用    
  186. #386楼 窜天下[未注册用户]2008-09-15 09:41
    笔误多了一点啊,呵呵
      回复  引用    
  187. #387楼 窜天下[未注册用户]2008-09-15 09:47
    你能给我也发一份吧,我的邮箱是levinyang@gmail.com,我研究研究.
      回复  引用    
  188. #388楼 tc11o8      2008-09-18 11:54
    我觉得 用usercontrol 来做html生成 有一些问题
    这样会带来臃于数据的返回 控件中的一些无用的脚本 标签等也都被重复返回到了客户端 这样的做法实现类似于updatepanel 与服务器交互中 数据的传输量丝毫没有减少 还是传统的把整个页面返回到客户端 对网络带宽就得有一定要求了
    我觉得web程序还是最好把有用的数据来进行传输 将数据进行定义成某一格式 比如json,xml等 这样就能带来web服务器数据的复用 虽然开发上可能会复杂一些 但这样实现了松耦合 可以多人开发这个程序 一个做页面处理 一个做服务端开发 彼此可以独立的进行开发 只要他们定义好数据交互的格式就行
      回复  引用  查看    
  189. #389楼[楼主] Jeffrey Zhao      2008-09-21 13:18
    @tc11o8
    文章说了这种做法有利有弊的
      回复  引用  查看    
  190. #390楼 tc11o8      2008-09-21 15:00
    谢谢 楼主 我也常看你的视频教程 :)
      回复  引用  查看    
  191. #391楼 gjj[未注册用户]2008-10-30 15:16
    ViewManager<ItemComments> viewManager = new ViewManager<ItemComments>();
    itemComments
    ItemComments是不能引用出来的
      回复  引用    
  192. #392楼 小涂[未注册用户]2008-10-31 12:57
    博主 你好 看了你的文章很感兴趣,
    但我技术比较差 看的不是很明白
    我想问一下 这个用户控件做HTML生成有没有例子,能不能发个给我研究一下,我现在用到了这个 很想了解 学会 谢谢了 有的话发个到我邮箱给我 真的感谢
      回复  引用    
  193. #393楼 nick_temp[未注册用户]2008-12-27 02:28
    //老赵:如果加载的用户控件用了缓存的话,是存在问题的。
    //我在网上找了一些资料,但还是没有解决问题
    //((PartialCachingControl)crl).CachedControl这上值一直是null.
    //所以没有办法实例化控件。
    链接地址:http://www.aspnetpro.com/NewsletterArticle/2003/08/asp200308pj_l/asp200308pj_l.asp
    他的例子是在一个页面里加载的用户控件,而你的是实例化一个页面容器来
    加载用户控件的。

    //下面是我的代码。
    public class ViewManager<T> where T : UserControl
    {
    private PageContainer m_pageHolder;

    public T LoadViewControl(string path)
    {
    this.m_pageHolder = new PageContainer();
    Control crl = this.m_pageHolder.LoadControl(path);
    Control currentCrl = null;
    if (crl is T)
    {
    currentCrl = crl;
    }
    else if (crl is PartialCachingControl && ((PartialCachingControl)crl).CachedControl != null)
    {
    currentCrl = ((PartialCachingControl)crl).CachedControl;
    }
    return (T)currentCrl;
    }

    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();
    }
    }
      回复  引用    
  194. #394楼 fengO[未注册用户]2009-01-16 10:13
    我把代码放在了Web服务的后置代码文件中,再现了下面的错误,

    编译错误
    说明: 在编译向该请求提供服务所需资源的过程中出现错误。请检查下列特定错误详细信息并适当地修改源代码。

    编译器错误信息: CS0246: The type or namespace name 'PagingData' could not be found (are you missing a using directive or an assembly reference?)

    如果放在一个.asmx文件中就可以,不知道其它人有没有这样的事情发生过,有没有什么解决方法?
      回复  引用    
  195. #395楼 renshivs[未注册用户]2009-02-06 17:03
    --引用--------------------------------------------------
    gjj: ViewManager&lt;ItemComments&gt; viewManager = new ViewManager&lt;ItemComments&gt;();
    itemComments
    ItemComments是不能引用出来的

    --------------------------------------------------------
    我也无法引用,不知道赵老师能不能解答下?
      回复  引用    
  196. #396楼 zachary[未注册用户]2009-03-10 13:49
    你好,老赵
    看了你的代码自己也在项目中想用一把
    结果却是在HttpHandler类里动态加载ascx时候报编译错:找不到类型或命名空间名称
    我用的是2005开发的,能不能将你的代码发我一份,让我研究学习一下呢
    我的邮箱地址:zachary.woo@163.com
      回复  引用    
  197. #397楼 彭白洋      2009-03-30 18:35
    楼主,您好!问个低级的问题啊:嘿嘿

    这事您的代码:

    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();
    }
    }


    我想问的是,为什么不再ashx也中直接用
    context.Server.Execute("~/ItemComments.ascx",output,false);呢?
    为什么要先放到容器中执行一下呢?

    StringWriter output = new StringWriter();
    context.Server.Execute("~/ItemComments.ascx", output, false);
    context.Response.Write(output);

    这个地方小弟很迷惑 谢谢楼主解答……
      回复  引用  查看    
  198. #398楼[楼主] Jeffrey Zhao      2009-03-30 20:10
    @彭白洋
    1、真可以吗?
    2、参数如何设置?
      回复  引用  查看    
  199. #399楼 彭白洋      2009-03-31 13:03
    我用的 vs2008 .net3.5
    是可以的
    不用定义一个容器 重新加载一下控件的


    就是这样:
    StringWriter output = new StringWriter();
    context.Server.Execute("~/ItemComments.ascx", output, false);
    context.Response.Write(output);


    Execute有一个这样的 重载方法的
      回复  引用  查看    
  200. #400楼[楼主] Jeffrey Zhao      2009-03-31 15:20
    @彭白洋
    参数可以设置吗?
      回复  引用  查看    
  201. 评论共2页: 上一页 1 2 



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1021297




相关文章:

相关链接: