Hello World
Spiga

技巧:使用User Control做HTML生成

2007-12-30 23:06 by 老赵, 21247 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本身不会带来任何额外的内容。

所属话题:WebForms与MVC
Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

Add your comment

252 条回复

  1. Hunts.C
    *.*.*.*
    链接

    Hunts.C 2007-12-30 23:19:00

    Good Job!

  2. lexus
    *.*.*.*
    链接

    lexus 2007-12-30 23:24:00

    没看得太明白,可能是看得不够仔细,

  3. 老赵
    admin
    链接

    老赵 2007-12-30 23:29:00

    @lexus
    建议自己运行一下。:)

  4. 一个农民[未注册用户]
    *.*.*.*
    链接

    一个农民[未注册用户] 2007-12-30 23:34:00

    你是小强呀!还有什么好东西,都拿出来吧!哈哈!

  5. pccai
    *.*.*.*
    链接

    pccai 2007-12-30 23:38:00

    sha fa!

  6. 一个农民[未注册用户]
    *.*.*.*
    链接

    一个农民[未注册用户] 2007-12-31 00:04:00

    泛型,匿名方法, HttpHandler ,prototype,都是我没有用过的东东。
    真强!

  7. 一个农民[未注册用户]
    *.*.*.*
    链接

    一个农民[未注册用户] 2007-12-31 00:10:00

    还有关于单元测试的文章,楼主一定要抽空写哦, 等我有有钱了就来收购楼主的公司,哈哈!

  8. 深蓝
    *.*.*.*
    链接

    深蓝 2007-12-31 00:11:00

    我一般使用自定义服务器控件来做,用户控件只是个控件的集合器。

  9. 阿不
    *.*.*.*
    链接

    阿不 2007-12-31 00:15:00

    很早就在用了,是从ScottGu那边抄过来的。

  10. 老赵
    admin
    链接

    老赵 2007-12-31 00:17:00

    @一个农民
    哪来匿名方法。

  11. 老赵
    admin
    链接

    老赵 2007-12-31 00:18:00

    @一个农民
    单元测试那个做不好。

  12. 老赵
    admin
    链接

    老赵 2007-12-31 00:18:00

    @深蓝
    服务器控件开发效率太低,还不能让美工参与进来。如果只是自己项目用的话,实在没有必要这么做。

  13. 老赵
    admin
    链接

    老赵 2007-12-31 00:19:00

    @阿不
    对的对的,有过那么一片文章。

  14. Clingingboy
    *.*.*.*
    链接

    Clingingboy 2007-12-31 00:29:00

    呵呵,其实这个做法跟ComponentArt的CallBack控件很相似.
    我认为用UserControl可以随时的满足ajax与传统网页的互换,如果你已经在网页中使用了UserControl,同时又想改成ajax加载可以在Render方法中输出控件的字符串.我自己做的blog就是用这种方式.我也比较喜欢:)

    可参考此文
    http://www.cnblogs.com/Clingingboy/archive/2007/07/10/812688.html

  15. Clingingboy
    *.*.*.*
    链接

    Clingingboy 2007-12-31 00:32:00

    说实话的,我们可以采用HTMLControl,因为我发现可以通过适配器改变控件ID和Name的输出方式.
    WebControl也是可以的,用HTMLControl更容易与美工结合,ID,后端功能都可以满足

  16. 老赵
    admin
    链接

    老赵 2007-12-31 00:39:00

    @Clingingboy
    你的blog是啥子?

  17. Clingingboy
    *.*.*.*
    链接

    Clingingboy 2007-12-31 00:41:00

    不过我没发现HttpServerUtility的Execute方法,所以没写在HttpHandler,学了一招:)

  18. egmkang
    *.*.*.*
    链接

    egmkang 2007-12-31 00:41:00

    我是一新手.看了半天,想着应该是想把 用户控件 当作一个简化的aspx页面,产生html代码,提供客户端异步刷新页面,对不对?

  19. Clingingboy
    *.*.*.*
    链接

    Clingingboy 2007-12-31 00:42:00

    @Jeffrey Zhao
    就是自己做着玩的
    www.clingingboy.cn

  20. sunlife
    *.*.*.*
    链接

    sunlife 2007-12-31 01:00:00

    你好,看了你的一些文章,我想请教您一个问题:在做网站时是不是自己尽量不要用服务器控件,如果是这样,那我们怎么用webform中比较重要的control模型来开发一些控件使用呢?如果我们开发一些没有UI的控件,那样我们的效率是不是就不高了.我想问一下,对于开发网站来说,考虑到和美工的结合,我们应该采用什么样的编程方式,才能够更好?

  21. 老赵
    admin
    链接

    老赵 2007-12-31 01:16:00

    @egmkang
    嗯啊,的确可以这样。

  22. 老赵
    admin
    链接

    老赵 2007-12-31 01:17:00

    @Clingingboy
    好像这个AJAX的不利于SEO啊,呵呵。

  23. 老赵
    admin
    链接

    老赵 2007-12-31 01:17:00

    @sunlife
    简单的服务器端控件,比如TextBox,Panel,Button,DropDownList(简单改造后)等等都可以使用。

  24. 怪怪
    *.*.*.*
    链接

    怪怪 2007-12-31 03:38:00

    支持一下^^

    你是言出必行, 我是说话不算话, 从第一次上你博客答应给别人的WebPart Hack到后来很多东西, 一个都没放出来(主要是很多都是随手写的我自己一个人用的版本, 觉得写得太乱, 怕人笑话, 这个心理老克服不了, 可是细心整理的基本没什么缺陷的时间又没有)

    所以我觉得大家都应该多谢老赵这样的热心人, 毕竟都要花很多功夫的.

  25. 烟头上的探戈
    *.*.*.*
    链接

    烟头上的探戈 2007-12-31 03:53:00

    学习了!

  26. 小宇gg[未注册用户]
    *.*.*.*
    链接

    小宇gg[未注册用户] 2007-12-31 09:25:00

    没看太懂...很复杂的说..

    最后的if片段有点像asp...

    飘...

  27. YanziMyWife
    *.*.*.*
    链接

    YanziMyWife 2007-12-31 09:26:00

    怎么老赵的BLOG用MAXTHON2进会死掉啊!

  28. 年华[未注册用户]
    *.*.*.*
    链接

    年华[未注册用户] 2007-12-31 09:59:00

    好东西 以前也想过这样做,但是不知道用户控件怎样生成html代码,学习了

    感谢老赵!!!

  29. 老赵
    admin
    链接

    老赵 2007-12-31 10:05:00

    @怪怪
    我的这些容易写,呵呵。

  30. 老赵
    admin
    链接

    老赵 2007-12-31 10:06:00

    @YanziMyWife
    是吗?有没有具体的症状?

  31. dusonchen[未注册用户]
    *.*.*.*
    链接

    dusonchen[未注册用户] 2007-12-31 10:13:00

    prototype,jquery,extjs三者,老赵你觉得哪个比较有优势呢?

  32. winken21[未注册用户]
    *.*.*.*
    链接

    winken21[未注册用户] 2007-12-31 10:59:00

    过年了...
    一起床就看到好文章...
    哈哈...
    最近还正想用呢...

  33. SZW
    *.*.*.*
    链接

    SZW 2007-12-31 11:13:00

    extjs太大了,只是效果比酷现成的功能多一点(像ASP.NET AJAX Toolkit那样),jquery属于“轻量级”的,完全自己开发的话我个人还是选择了jquery。不过要说和WebForm结合的好的话,当然还是Extjs,jquery在DOM操作上和WebForm的衔接让人不爽。

    老赵,"&t=" + new Date()在你这只是为了区分同一页面的不同URL字段,防止重新载入时不能刷新(就像有的验证码那样),还是有别的用途?

  34. 老赵
    admin
    链接

    老赵 2007-12-31 11:39:00

    @SZW
    AJAX的GET操作可能会在IE下被缓存,用不同URL是为了避免这点。

  35. SZW
    *.*.*.*
    链接

    SZW 2007-12-31 11:41:00

    恩,我第一点就是这个意思,我做那些AJAX的验证码也只想到了这个方法,之前一直在寻找更好的办法,不过我用jquery做ajax的时候好像可以直接避免这个问题

    补充一点,有时候即使不是ajax的缓存,只是一个img/src之类的,也需要用这个方法去做,因为同样的URL浏览器是不会重新载入的,就像我们使用#name标签那样,不过就不只在AJAX范围内了

  36. Clingingboy
    *.*.*.*
    链接

    Clingingboy 2007-12-31 11:44:00

    把标签头 If-Modified-Since设置为0就可以了,我直接手动改了prototype的代码加了一句
    Firefox没这个问题

  37. BlackCat
    *.*.*.*
    链接

    BlackCat 2007-12-31 12:02:00

    放假了,但是园子里依然热闹,支持一下

  38. 隐姓埋名
    *.*.*.*
    链接

    隐姓埋名 2007-12-31 12:29:00

    才学初浅!
    似懂非懂!

    继续关注!!!

    谢谢!!!

  39. 张荣华
    *.*.*.*
    链接

    张荣华 2007-12-31 14:00:00

    学习中
    不过赵老大是不是在ViewItem.Page_Load中忘了赋值PageSize属性呢

  40. stonezhu
    *.*.*.*
    链接

    stonezhu 2007-12-31 14:11:00

    呵呵,赞一个,看来真是孤陋寡闻,老赵真有一套啊,这个方法不错。自己开发方便,又提高了UserControl的利用率,UserControl确实做得不错,生成不加垃圾代码,只是一个DIV,
    期待老赵多出经典

    祝 元旦快乐

  41. 老赵
    admin
    链接

    老赵 2007-12-31 14:19:00

    @stonezhu
    哪来DIV啊,DIV是我在aspx里加的。
    UserControl一点多余代码也没有。

  42. stonezhu
    *.*.*.*
    链接

    stonezhu 2007-12-31 14:42:00

    @Jeffrey Zhao
    噢,刚才想到了Panel :)
    Panel加了后是一个DIV, UserControl是没有东西的,呵呵
    头晕了.2007的最后一次头晕:)

  43. 金色海洋(jyk)
    *.*.*.*
    链接

    金色海洋(jyk) 2007-12-31 15:56:00

    老大就是老大,这么多人回复。

  44. Awen7501[未注册用户]
    *.*.*.*
    链接

    Awen7501[未注册用户] 2007-12-31 16:11:00

    好文!希望园子里面这类型的文章多点,^_^,支持!

  45. 不明白[未注册用户]
    *.*.*.*
    链接

    不明白[未注册用户] 2007-12-31 17:39:00

    private static List<Comment> s_comments = new List<Comment>
    {
    new Comment
    {
    CreateTime = DateTime.Parse("2007-1-1"),
    Content = "今天天气不错"
    },
    ......
    };
    这是什么写法啊。怎么看不懂啊?

  46. 不明白[未注册用户]
    *.*.*.*
    链接

    不明白[未注册用户] 2007-12-31 17:46:00

    new表达式后面可以是{}??文章不错。就这个地方不明白。

  47. 老赵
    admin
    链接

    老赵 2007-12-31 19:03:00

    @不明白
    C#3.0的object initializer

  48. Melodicsoul
    *.*.*.*
    链接

    Melodicsoul 2007-12-31 21:27:00

    不错啊,又是另一种思路,有时间我也试下,感谢分享!

  49. HSimon[未注册用户]
    *.*.*.*
    链接

    HSimon[未注册用户] 2008-01-01 01:08:00

    感谢分享。
    请问一下
    public class ViewManager<T> where T
    这种语法是什么,能推荐一些相关的资料么?

  50. 老赵
    admin
    链接

    老赵 2008-01-01 01:29:00

    @HSimon
    范型(Generic)。
    资料网上或MSDN一搜一大把,有点年份的东西了,需要跟进了,呵呵。:)

  51. 啊东
    *.*.*.*
    链接

    啊东 2008-01-02 11:36:00

    多谢分享...

  52. doublog[未注册用户]
    *.*.*.*
    链接

    doublog[未注册用户] 2008-01-02 14:23:00

    这个和飞鸽写的哪个教程差不多 呵呵

    我一直用这种方法,但是我不知道这种方法效率如何?
    老赵 啥时候评测一下?

  53. 老赵
    admin
    链接

    老赵 2008-01-02 14:33:00

    @doublog
    性能和普通的ASP.NET WebForms一样。

  54. 武眉博<活靶子.Net>
    *.*.*.*
    链接

    武眉博<活靶子.Net> 2008-01-02 15:25:00

    这个很好!我以前为了考虑SEO 先判断浏览器Agent如果是常见蜘蛛那么分页代码就/xx.pageindex.aspx 如果不是那就ajax的,今天又学习一招。

  55. doublog[未注册用户]
    *.*.*.*
    链接

    doublog[未注册用户] 2008-01-02 16:25:00

    --引用--------------------------------------------------
    武眉博&lt;活靶子.Net&gt;: 这个很好!我以前为了考虑SEO 先判断浏览器Agent如果是常见蜘蛛那么分页代码就/xx.pageindex.aspx 如果不是那就ajax的,今天又学习一招。
    --------------------------------------------------------
    你狠啊 看来为了蜘蛛什么都能想的出来啊

  56. sunny11[未注册用户]
    *.*.*.*
    链接

    sunny11[未注册用户] 2008-01-02 17:44:00

    请问一下,做大型社会网站,用ORM会存在性能问题吗,请问可以用ORM映射吗?

  57. sunny11[未注册用户]
    *.*.*.*
    链接

    sunny11[未注册用户] 2008-01-02 17:46:00

    网站和企业应用,关注点不一样,企业应用可能用,它关注的是业务,同时使用的人数也不会很多,但是大型网站可能访问量就很高,用ORM是不是就不好了

  58. 老赵
    admin
    链接

    老赵 2008-01-02 17:50:00

    @sunny11
    很难造成性能瓶颈。

  59. 老赵
    admin
    链接

    老赵 2008-01-02 17:50:00

    --引用--------------------------------------------------
    doublog: --引用--------------------------------------------------
    武眉博&lt;活靶子.Net&gt;: 这个很好!我以前为了考虑SEO 先判断浏览器Agent如果是常见蜘蛛那么分页代码就/xx.pageindex.aspx 如果不是那就ajax的,今天又学习一招。
    --------------------------------------------------------
    你狠啊 看来为了蜘蛛什么都能想的出来啊
    --------------------------------------------------------
    会不会被搜索引擎判作弊?

  60. sunny11[未注册用户]
    *.*.*.*
    链接

    sunny11[未注册用户] 2008-01-02 18:34:00

    很难造成性能瓶颈??

  61. sunny11[未注册用户]
    *.*.*.*
    链接

    sunny11[未注册用户] 2008-01-02 18:41:00

    用ORM效率是不高的

  62. 老赵
    admin
    链接

    老赵 2008-01-02 20:39:00

    @sunny11
    相对于许多东西都自己写,自然效率比较低,但是一个系统的性能问题不太会是ORM造成的。性能自有瓶颈,而这个瓶颈不太会是ORM。

  63. 武眉博<活靶子.Net>
    *.*.*.*
    链接

    武眉博<活靶子.Net> 2008-01-02 20:45:00

    --引用--------------------------------------------------
    Jeffrey Zhao: --引用--------------------------------------------------
    doublog: --引用--------------------------------------------------
    武眉博&lt;活靶子.Net&gt;: 这个很好!我以前为了考虑SEO 先判断浏览器Agent如果是常见蜘蛛那么分页代码就/xx.pageindex.aspx 如果不是那就ajax的,今天又学习一招。
    --------------------------------------------------------
    你狠啊 看来为了蜘蛛什么都能想的出来啊
    --------------------------------------------------------
    会不会被搜索引擎判作弊?
    --------------------------------------------------------
    根据到目前的观察 并没有 而且我认为这个也不构成作弊 就像我用了ajax又要兼顾SEO在sitemap.aspx中给实际链接一样的

  64. 老赵
    admin
    链接

    老赵 2008-01-02 20:54:00

    @武眉博<活靶子.Net>
    其实不一样的。理论上如果特意为搜索引擎“制作”和普通用户访问不同的页面,是会被认作作弊的。不过其实你这个应该还好,因为修改的地方不多。呵呵。

  65. 小鹿
    *.*.*.*
    链接

    小鹿 2008-01-02 22:23:00

    new Ajax.Updater(
    "comments",
    "/GetComments.ashx?page=" + pageIndex + "&t=" + new Date(),
    { method: "get" });
    Ajax.Updater是prototype里面的吗 不怎么明白

  66. 1-2-3
    *.*.*.*
    链接

    1-2-3 2008-01-03 09:49:00

    非常实用。收藏。

  67. 老赵
    admin
    链接

    老赵 2008-01-03 11:25:00

    @小鹿
    Ajax.Updater方法是prototype里的。

  68. HSimon[未注册用户]
    *.*.*.*
    链接

    HSimon[未注册用户] 2008-01-03 16:51:00

    @Jeffrey Zhao
    谢谢!
    <T>这个知道,主要是后面那个“where T” 不是很理解。还希望说说
    :)

  69. 老赵
    admin
    链接

    老赵 2008-01-03 19:23:00

    --引用--------------------------------------------------
    HSimon: @Jeffrey Zhao
    谢谢!
    <T>这个知道,主要是后面那个“where T” 不是很理解。还希望说说
    :)
    --------------------------------------------------------
    泛型约束,具体查文档吧

  70. HSimon[未注册用户]
    *.*.*.*
    链接

    HSimon[未注册用户] 2008-01-04 10:34:00

    @Jeffrey Zhao
    Thanks,:)

  71. 马可香蕉
    *.*.*.*
    链接

    马可香蕉 2008-01-04 15:31:00

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

    方法第一个参数应该是IHttpHandler类型的,为什么Page类型也可以,Page继承IHttpHandler吗?

  72. SZW
    *.*.*.*
    链接

    SZW 2008-01-04 17:16:00

    @sunny11
    --引用--------------------------------------------------
    sunny11: 用ORM效率是不高的
    --------------------------------------------------------
    我在用.net3.5时候也一直也在考虑这个问题,不过看了一些测评,似乎这个“效率”高低的差别也只是在数据比较少的情况下表现得出来,数据很多的话ORM的效率就慢慢显现出来了,不过我没有亲自测试过,不知否有更可靠的数据。所以对大点的项目我还是比较“观望”ORM。

    如果那些测试结果是真实的,那这个问题也变得很辩证:小网站,不在乎细微的“效率”问题,ORM随便用;某些大网站,既然ORM可以提高开发效率,同时数据量大的时候ORM也不存在“降低效率”问题,还是可以考虑用。

  73. aaaa[未注册用户]
    *.*.*.*
    链接

    aaaa[未注册用户] 2008-01-04 18:06:00

    代码有错

  74. jas[未注册用户]
    *.*.*.*
    链接

    jas[未注册用户] 2008-01-04 18:34:00

    多谢楼主好文! 我在做的时候,有一个问题, 我把viewmanager.cs 和GetComments 放在app_code folder里面, ItemComments.ascx在根目录下面,但是在getCommments里面的 Itemcomments却不能识别,所以编译出错。请帮助!

  75. jun_brave[未注册用户]
    *.*.*.*
    链接

    jun_brave[未注册用户] 2008-01-04 19:50:00

    楼上说的跟我的情况差不多,不过我的搞笑点,有时候能通过,有时候报错,说找不到Itemcomments.......
    不清楚什么情况!

  76. jun_brave[未注册用户]
    *.*.*.*
    链接

    jun_brave[未注册用户] 2008-01-04 19:53:00

    更正下,我那个错误是在GetComments.ashx中,就是不知道为什么有时候能通过,有时候就报错!!
    谢谢楼主的文章.........

  77. 老赵
    admin
    链接

    老赵 2008-01-05 01:15:00

    @jas
    用外部Class Library。

  78. 静旅
    *.*.*.*
    链接

    静旅 2008-01-05 01:29:00

    老赵,怎么进这个页面,老是卡卡的。
    还说,这篇文章有没有源程序的。

  79. ll1[未注册用户]
    *.*.*.*
    链接

    ll1[未注册用户] 2008-01-05 02:57:00

    执行处理程序“System.Web.UI.Page”的子请求时出错

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

    在这里出现异常?望楼主指点!

  80. 老赵
    admin
    链接

    老赵 2008-01-05 09:39:00

    @ll1
    一模一样的代码吗?

  81. 老赵
    admin
    链接

    老赵 2008-01-05 09:40:00

    @静旅
    所有的源代码都贴出来了阿。

  82. ll1[未注册用户]
    *.*.*.*
    链接

    ll1[未注册用户] 2008-01-05 11:19:00

    @Jeffrey Zhao
    代码基本相同,我只是把数据改成从数据库中取得,编译时有时能通过,有时报错,加断点就出现上面说的异常.
    在ashx文件中也是Itemcomments不能识别,不过有时候又能通过!

  83. ll1[未注册用户]
    *.*.*.*
    链接

    ll1[未注册用户] 2008-01-05 11:20:00

    @Jeffrey Zhao
    忘记说了,我用的是2005的,应该没什么问题吧

  84. 老赵
    admin
    链接

    老赵 2008-01-05 11:51:00

    @ll1
    用外部引用Class Library吧,2005也没事的。

  85. ll1[未注册用户]
    *.*.*.*
    链接

    ll1[未注册用户] 2008-01-05 12:02:00

    @Jeffrey Zhao
    外部引用Class Library,应该如何做呢?
    我奇怪的是他为什么有时候能通过,有时候出错!

  86. ll1[未注册用户]
    *.*.*.*
    链接

    ll1[未注册用户] 2008-01-05 20:48:00

    楼主,谢谢你的文章,我加了个using System.Web.UI;
    把Itemcomments直接改成UserControl后错误消失了!

  87. ll1[未注册用户]
    *.*.*.*
    链接

    ll1[未注册用户] 2008-01-05 21:10:00

    @Jeffrey Zhao
    new Ajax.Updater(
    "comments",
    "/GetComments.ashx?page=" + pageIndex + "&t=" + new Date(),
    { method: "get" });
    这样的功能请问用JS直接实现能行么?

  88. luyong[未注册用户]
    *.*.*.*
    链接

    luyong[未注册用户] 2008-01-05 22:43:00

    httpHandlers怎么加呢?
    我试了下
    <add verb="GET" path="GetComments.ashx" type="GetComments,MyUserControl"/>
    我是用vs2008建的asp.net web site,handler直接是使用你给的类,没做过修改,MyUserControl是工程的文件名,但还是出错:
    分析器错误信息: 未能加载文件或程序集“MyUserControl”或它的某一个依赖项。系统找不到指定的文件。

  89. beyoung
    *.*.*.*
    链接

    beyoung 2008-01-06 00:01:00

    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是什么呢?怎么来的?

  90. 老赵
    admin
    链接

    老赵 2008-01-06 01:19:00

    @beyoung
    ascx里有的。

  91. 老赵
    admin
    链接

    老赵 2008-01-06 01:19:00

    @luyong
    ashx是供直接调用的,不是用来配置的。

  92. luyong[未注册用户]
    *.*.*.*
    链接

    luyong[未注册用户] 2008-01-06 11:38:00

    @Jeffrey Zhao
    谢谢
    另外,getComments(pageIndex)中return false; // IE only
    是不是要改为return true?
    另外运行点击下一页时,页面还是要重刷一下
    prototype中的Ajax.Updater中的"comments"是做什么用的?

  93. luyong[未注册用户]
    *.*.*.*
    链接

    luyong[未注册用户] 2008-01-06 16:12:00

    哦,原来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>

  94. beyoung
    *.*.*.*
    链接

    beyoung 2008-01-06 21:00:00

    关于OnPreRender的用法,MSDN中这样说:"通过查找文件数据或调用用户事件获取要呈现的广告信息。"
    我不是很明白,这个方法一般都用在什么地方,是什么意思呢?
    谢谢你的回复:)

  95. 老赵
    admin
    链接

    老赵 2008-01-07 01:30:00

    @luyong
    看编程的概念吧。我这里把逻辑都放在aspx中,ascx只管呈现。

  96. 老赵
    admin
    链接

    老赵 2008-01-07 01:31:00

    @beyoung
    其实……我也不知道。
    我只是知道每个生命周期的意义和执行顺序等等,然后在合时的地方使用它。

  97. feng173[未注册用户]
    *.*.*.*
    链接

    feng173[未注册用户] 2008-01-07 09:16:00

    我也是在这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);这里也出错,实在没办法,望您指教

  98. 夕阳夕下
    *.*.*.*
    链接

    夕阳夕下 2008-01-07 16:55:00

    好帖,当然就要回帖,写得不错,收藏!

  99. jas[未注册用户]
    *.*.*.*
    链接

    jas[未注册用户] 2008-01-07 17:57:00

    可不可以麻烦楼主把源码打个包,我想下载下来看一下。我的问题还是无法解决,谢谢

  100. wade311[未注册用户]
    *.*.*.*
    链接

    wade311[未注册用户] 2008-01-07 18:12:00

    不知道楼主注意到当 ItemComments 中包含服务器控件时其在 m_pageHolder 中初始化时有问题

  101. wade311[未注册用户]
    *.*.*.*
    链接

    wade311[未注册用户] 2008-01-07 18:52:00



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

    望楼主解惑,xiexie

  102. 老赵
    admin
    链接

    老赵 2008-01-08 00:46:00

    @wade311
    重写一个Page容器,覆盖掉一个VerifyXXX方法,具体查一下吧。

  103. ll1[未注册用户]
    *.*.*.*
    链接

    ll1[未注册用户] 2008-01-08 13:28:00

    @wade311
    你可以只在usercontrol中加datalist或者datarepeater,服务器端控件在这里面是不会报错的,其他不是放在datalist中的服务器控件你可以放到要显示这个usercontrol的aspx页中,那样操作也会更加简单

  104. ll1[未注册用户]
    *.*.*.*
    链接

    ll1[未注册用户] 2008-01-08 13:32:00

    老赵啊,你的这个博客是不是中毒了?每次进来都要好长时间....

  105. 马可香蕉
    *.*.*.*
    链接

    马可香蕉 2008-01-08 16:39:00

    问个问题:为什么我在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());

    这样不行

  106. 老赵
    admin
    链接

    老赵 2008-01-08 19:29:00

    @ll1
    不知道别人有这个问题吗?

  107. 老赵
    admin
    链接

    老赵 2008-01-08 19:29:00

    @马可香蕉
    控件需要过生命周期

  108. Evi[未注册用户]
    *.*.*.*
    链接

    Evi[未注册用户] 2008-01-08 20:29:00

    UserControl里能不能放置TextBox和Button,然后通过点击Button提交表单呢?似乎不行。表单提交到了页面里去了。根本不会触发UserControl里Button的Click事件。如果我想提交表单该如何做?

  109. Evi[未注册用户]
    *.*.*.*
    链接

    Evi[未注册用户] 2008-01-08 21:04:00

    @ll1
    @Jeffrey Zhao
    博客进来慢可能跟Window Live Message有关。每次进来时看到页面的内容下载完了。点击浏览器的"停止"就可以了。

  110. 老赵
    admin
    链接

    老赵 2008-01-08 22:12:00

    @Evi
    我的这个技巧只是用来生成HTML代码的。
    你的要求是需要动态加载控件了。在我这里搜索SwitchPartManager,可能对你有帮助。

  111. 马可香蕉
    *.*.*.*
    链接

    马可香蕉 2008-01-09 16:15:00

    @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进来

  112. 老赵
    admin
    链接

    老赵 2008-01-09 17:31:00

    @马可香蕉
    Load里除了new还做了其他的事情。让他过生命周期是因为“Execute”。

  113. 马可香蕉
    *.*.*.*
    链接

    马可香蕉 2008-01-10 10:09:00

    @Jeffrey Zhao
    谢谢:)
    到底Load里还做了什么事情,我搜索了下没搜到什么东西

  114. guogu82
    *.*.*.*
    链接

    guogu82 2008-01-14 17:12:00

    看完啦,眼睛疼。

  115. 蓝天旭日
    *.*.*.*
    链接

    蓝天旭日 2008-01-16 10:40:00

    强人!

  116. Osamede
    *.*.*.*
    链接

    Osamede 2008-01-16 15:25:00

    好文

  117. Cat Chen
    *.*.*.*
    链接

    Cat Chen 2008-01-16 15:56:00

    说到底,ASPX在Jeffrey手上就是一个纯粹的模板引擎,哈哈。

  118. 老赵
    admin
    链接

    老赵 2008-01-16 18:12:00

    @Cat Chen
    啥时也研究研究MVC的做法,hoho。

  119. Pandor Cai[未注册用户]
    *.*.*.*
    链接

    Pandor Cai[未注册用户] 2008-01-18 00:58:00

    public class ViewManager<T> where T : UserControl
    为什么不直接写
    public class ViewManager<UserControl>

  120. 老赵
    admin
    链接

    老赵 2008-01-18 01:45:00

    @Pandor Cai
    嗯?范型能这样使用吗?

  121. 小庄
    *.*.*.*
    链接

    小庄 2008-01-21 08:50:00

    好办法!居然绕过了客户端的数据绑定!我打算把这个改成asp.net ajax的,真是谢谢!

  122. llinzzi[未注册用户]
    *.*.*.*
    链接

    llinzzi[未注册用户] 2008-01-26 15:21:00

    老赵这个方法很实用,受益匪浅。应该说颇为完美。
    优点是同一个ascx为ashx和aspx输出内容
    可这又让我联想到 在这里ascx我理解为了逻辑层,ashx和aspx作为了两种表现层,作为逻辑层提供出来的数据掺杂了html,不方便其他表现层应用程序调用。而且逻辑上不完美。
    如果把这里的ascx要做的事情放到webservice中,为aspx输出xml,为ajax输出json,似乎更完美写,也就是用ws事先所有逻辑。aspx制作数据格式化绑定并显示等。并可以给更多种形式的客户端提供便利。
    只不过客户端要进行dom操作了,比较麻烦。但理论上这种模式比较完美。
    以上的老赵肯定也想过。说起来简单,做起来很麻烦。就是想到哪说到哪,还请老赵见谅

  123. pioman[未注册用户]
    *.*.*.*
    链接

    pioman[未注册用户] 2008-01-30 15:17:00

    代码看其来很优美

  124. 小兵a[未注册用户]
    *.*.*.*
    链接

    小兵a[未注册用户] 2008-02-13 16:56:00

    做不出来

  125. BAsil
    *.*.*.*
    链接

    BAsil 2008-02-18 13:44:00

    请问赵哥在net 1.1有没有相应的解决方案?Server.Execute不支持IHttpHandler参数

  126. 老赵
    admin
    链接

    老赵 2008-02-18 14:49:00

    @BAsil
    不好意思,我没有1.1的环境了。:(

  127. XL_ALEX[未注册用户]
    *.*.*.*
    链接

    XL_ALEX[未注册用户] 2008-02-21 09:29:00

    好。。正好我们要静态化页面。

  128. 老赵
    admin
    链接

    老赵 2008-02-21 10:02:00

    @XL_ALEX
    这和静态页无关

  129. zyug[未注册用户]
    *.*.*.*
    链接

    zyug[未注册用户] 2008-02-21 10:46:00

    说到底,ASPX在Jeffrey手上就是一个纯粹的模板引擎,哈哈。


    说的太精辟了

  130. zyug[未注册用户]
    *.*.*.*
    链接

    zyug[未注册用户] 2008-02-21 14:13:00

    小弟有点不明白

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

    对此不是很理解,望能赐教

  131. 老赵
    admin
    链接

    老赵 2008-02-21 14:33:00

    @zyug
    一个辅助类啊

  132. WOW玩家
    *.*.*.*
    链接

    WOW玩家 2008-03-03 11:42:00

    这个方法好。我以前是用一个空的aspx页面+用户控件来生成html 进行ajax交互的。这个比我的先进。

  133. flyboy[未注册用户]
    *.*.*.*
    链接

    flyboy[未注册用户] 2008-03-04 22:13:00

    为什么不直接把用户控件放到updatepanel中去呢?这样多省事啊

  134. 老赵
    admin
    链接

    老赵 2008-03-04 22:39:00

    @flyboy
    一是性能问题。
    二是开发人员接受程度问题。
    所以我们没有用UpdatePanel。

  135. flyboy[未注册用户]
    *.*.*.*
    链接

    flyboy[未注册用户] 2008-03-12 08:19:00

    --引用--------------------------------------------------
    Jeffrey Zhao: @flyboy
    一是性能问题。
    二是开发人员接受程度问题。
    所以我们没有用UpdatePanel。
    --------------------------------------------------------

    知道了,谢谢老赵

  136. flyboy[未注册用户]
    *.*.*.*
    链接

    flyboy[未注册用户] 2008-03-12 22:43:00

    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#不是很熟。

  137. flyboy[未注册用户]
    *.*.*.*
    链接

    flyboy[未注册用户] 2008-03-13 00:42:00

    to Jeffrey Zhao

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

    不过有一个问题

    我在输入

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

    为什么啊???郁闷,今天搞了一天了,太晚了明天再搞,

  138. flyboy[未注册用户]
    *.*.*.*
    链接

    flyboy[未注册用户] 2008-03-13 08:13:00

    今天早上测试了一下
    如果在您的文件中加个服务器控件,也会报同样的错误,(<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>

  139. flyboy[未注册用户]
    *.*.*.*
    链接

    flyboy[未注册用户] 2008-03-13 08:23:00

    真是奇怪我测试了就是 Repeater ListView控件可以用,其他控件都会报错。
    老赵您在写DEMO时,有没有遇到同样的问题?有没有直接的办法或者变通的办法,因为我要用服务器端控件主要是想使用ajax toolkits

  140. 老赵
    admin
    链接

    老赵 2008-03-14 16:27:00

    @flyboy
    写一个新的Page类,把它的VerifyXXX方法override掉(留空即可),用它作为容器。

  141. 老赵
    admin
    链接

    老赵 2008-03-28 10:43:00

    @swing
    这个技术本就不适合使用AJAX Control Toolkit,赫赫。
    遇到问题具体问题具体分析就可以了。

  142. 凯凯[未注册用户]
    *.*.*.*
    链接

    凯凯[未注册用户] 2008-03-30 11:59:00

    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 = "这的确挺爽的"
    }
    这段怎么老提示有错误啊

  143. 老赵
    admin
    链接

    老赵 2008-03-30 14:55:00

    @凯凯
    这是C# 3.0的特性。

  144. 帝之晓
    *.*.*.*
    链接

    帝之晓 2008-04-03 10:14:00

    天那,评论那么长

  145. mclkyo[未注册用户]
    *.*.*.*
    链接

    mclkyo[未注册用户] 2008-04-15 09:27:00

    我还是没法找到那个用户控件的类
    不知道楼主能否详细讲一下怎么得到那个类,谢谢

  146. 老赵
    admin
    链接

    老赵 2008-04-15 10:09:00

    @mclkyo
    直接LoadControl就可以了阿,Cast成ascx.cs里的那个类。

  147. mclkyo[未注册用户]
    *.*.*.*
    链接

    mclkyo[未注册用户] 2008-04-15 16:41:00

    问题是在我的代码里面找不到ItemComments这个类
    也就是LoadControl后无法进行Cast啊
    就是ItemComments control = viewManager.LoadViewControl("~/ItemComments.ascx");这句代码,说无法识别ItemComments这个类
    所以也就无法对PageIndex,PageSize这个变量赋值啊
    请楼主解答,谢谢

  148. 老赵
    admin
    链接

    老赵 2008-04-16 00:34:00

    @mclkyo
    你的ItemComments.ascx.cs里写的是什么类阿?

  149. mclkyo[未注册用户]
    *.*.*.*
    链接

    mclkyo[未注册用户] 2008-04-16 08:59:00

    我用的是VS2005,用添加选项添加的UserControl的
    生成的代码为
    public partial class ItemComments : System.Web.UI.UserControl
    {
    }
    不知道为什么,在别的项面就是无法找到ItemComments这个类,奇怪了??

  150. 老赵
    admin
    链接

    老赵 2008-04-16 11:00:00

    @mclkyo
    别的项目?命名空间正确了没?

  151. mclkyo[未注册用户]
    *.*.*.*
    链接

    mclkyo[未注册用户] 2008-04-16 12:03:00

    项目,命名空间都没问题
    我发现在aspx.cs文件中要识别ItemComments这个类就必须在Aspx页面加上<%@ Register src=''%>头
    但在我如果要在AppCode的类里面引用ItemComments这个类就不知道怎么做了

  152. 老赵
    admin
    链接

    老赵 2008-04-16 20:47:00

    @mclkyo
    App_Code没有引用WebSite里的项目,自然无法使用。
    这段代码不能写在App_Code里。

  153. 希望回答[未注册用户]
    *.*.*.*
    链接

    希望回答[未注册用户] 2008-04-27 11:09:00

    麻烦问下 我的用户控件和ashx文件不是放在同一目录下
    ControlManager<HeadControl> viewManager = new ControlManager<HeadControl>();
    HeadControl control = viewManager.LoadViewControl("Controls/HeadControl.ascx");
    无法编译通过,用命名控件组织也不可以。想问下怎么解决。
    谢谢。。。。

  154. 老赵
    admin
    链接

    老赵 2008-04-27 14:37:00

    @希望回答
    放在额外的Class Library里。

  155. zys1202[未注册用户]
    *.*.*.*
    链接

    zys1202[未注册用户] 2008-05-07 13:44:00

    ControlManager<HeadControl> viewManager = new ControlManager<HeadControl>();
    HeadControl control = viewManager.LoadViewControl("Controls/HeadControl.ascx");
    无法编译通过,用命名控件组织也不可以。想问下怎么解决。
    找不到命名空间或类型名称 HeadControl

  156. 老赵
    admin
    链接

    老赵 2008-05-07 15:03:00

    HeadControl定义在什么地方?

  157. 五味果
    *.*.*.*
    链接

    五味果 2008-05-23 15:38:00

    老赵,你能把这个例子能提供下载或者给我邮箱发一份吗
    我的邮箱:taibaizhou@163.com
    我在调试你的例子时候遇到,
    ViewManager<ItemComments> viewManager = new ViewManager<ItemComments>();
    ItemComments control = viewManager.LoadViewControl("ItemComments.ascx");
    ItemComments类不能识别出来。
    麻烦你了!

  158. jim.chb[未注册用户]
    *.*.*.*
    链接

    jim.chb[未注册用户] 2008-06-01 23:25:00

    老赵,首先谢谢您的无私贡献哦!我在调试的时候遇到这个问题:执行到
    HttpContext.Current.Server.Execute(this.m_pageHolder, output, false);

    这里的时候,报错:

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

    老赵能给点思路么,多谢!

  159. jim.chb[未注册用户]
    *.*.*.*
    链接

    jim.chb[未注册用户] 2008-06-01 23:28:00

    其中的 output变量已经取出usercontrol的html字符串了 ,但就不能return呢?

  160. 老赵
    admin
    链接

    老赵 2008-06-02 00:10:00

    @jim.chb
    执行时出现异常?我的例子你能运行吗?

  161. r[未注册用户]
    *.*.*.*
    链接

    r[未注册用户] 2008-06-04 17:23:00

    看了,凑个数

  162. qinii[未注册用户]
    *.*.*.*
    链接

    qinii[未注册用户] 2008-06-04 19:53:00

    晕了。总算找到了。。。。。。。。。。。
    还是去年写的,郁闷~~~~一直认为可以这样实现,只怪本人对asp.net还深入学习,没办法自己实现。。。

  163. iceflying[未注册用户]
    *.*.*.*
    链接

    iceflying[未注册用户] 2008-06-05 15:29:00

    老赵 我无法在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;
    }
    }

    }

  164. beafhorse[未注册用户]
    *.*.*.*
    链接

    beafhorse[未注册用户] 2008-06-10 12:42:00

    能不能把这个东西和web service结合起来?

  165. beafhorse[未注册用户]
    *.*.*.*
    链接

    beafhorse[未注册用户] 2008-06-11 00:12:00

    还有个问题.如果UserControl里面也有javascript代码,这些代码会正常实现么?我测试了一下,似乎不行.

  166. 老赵
    admin
    链接

    老赵 2008-06-11 00:23:00

    --引用--------------------------------------------------
    beafhorse: 还有个问题.如果UserControl里面也有javascript代码,这些代码会正常实现么?我测试了一下,似乎不行.
    --------------------------------------------------------
    肯定不行的

  167. beafhorse[未注册用户]
    *.*.*.*
    链接

    beafhorse[未注册用户] 2008-06-11 14:33:00

    --引用--------------------------------------------------
    Jeffrey Zhao: --引用--------------------------------------------------
    beafhorse: 还有个问题.如果UserControl里面也有javascript代码,这些代码会正常实现么?我测试了一下,似乎不行.
    --------------------------------------------------------
    肯定不行的
    --------------------------------------------------------
    那如果UserControl中必须放入一些js代码的话,本文讲的这个方法是不是就不适用了?

  168. 老赵
    admin
    链接

    老赵 2008-06-11 16:08:00

    @beafhorse
    在这个基础上做点补充阿。

  169. beafhorse[未注册用户]
    *.*.*.*
    链接

    beafhorse[未注册用户] 2008-06-11 17:32:00

    --引用--------------------------------------------------
    Jeffrey Zhao: @beafhorse
    在这个基础上做点补充阿。
    --------------------------------------------------------
    如何做,给点提示吧.

  170. Eve[未注册用户]
    *.*.*.*
    链接

    Eve[未注册用户] 2008-06-13 04:50:00

    --引用--------------------------------------------------
    Jeffrey Zhao: --引用--------------------------------------------------
    beafhorse: 还有个问题.如果UserControl里面也有javascript代码,这些代码会正常实现么?我测试了一下,似乎不行.
    --------------------------------------------------------
    肯定不行的
    --------------------------------------------------------
    “UserControl里面也有javascript代码,这些代码会正常实现么?”指的是什么?
    又为什么肯定不行?
    我试了一下似乎都能运行啊?

  171. 老赵
    admin
    链接

    老赵 2008-06-13 10:34:00

    --引用--------------------------------------------------
    “UserControl里面也有javascript代码,这些代码会正常实现么?”指的是什么?
    又为什么肯定不行?
    我试了一下似乎都能运行啊?
    --------------------------------------------------------
    不可能的,你是在用我这种设置innerHTML的方式更新吗?

  172. beafhorse[未注册用户]
    *.*.*.*
    链接

    beafhorse[未注册用户] 2008-06-13 10:40:00

    --引用--------------------------------------------------
    Jeffrey Zhao: --引用--------------------------------------------------
    “UserControl里面也有javascript代码,这些代码会正常实现么?”指的是什么?
    又为什么肯定不行?
    我试了一下似乎都能运行啊?
    --------------------------------------------------------
    不可能的,你是在用我这种设置innerHTML的方式更新吗?
    --------------------------------------------------------
    那以何种方式更新可以让UserControl中的javascript代码正常执行呢?困惑了两天了.

  173. beafhorse[未注册用户]
    *.*.*.*
    链接

    beafhorse[未注册用户] 2008-06-13 11:23:00

    昨天看老赵的asp.net ajax教程,有了思路.
    把usercontrol里面的script代码提取出来.放在页面的head中解析.

    这样是否可行?还有更好的办法没?

  174. beafhorse[未注册用户]
    *.*.*.*
    链接

    beafhorse[未注册用户] 2008-06-13 11:31:00

    如果只考虑ie,加个defer就可以了.firefox有没有类似的标签?

  175. Sam Lin
    *.*.*.*
    链接

    Sam Lin 2008-06-13 18:51:00

    看了颇久代码,在把代码copy在vs2005 C#中,怎么老是出错~~~
    原来是C#3.0的新特性~啊,看来要开始学习3.0了
    好象从2.0到3.0新加的东西,大多是从javascript中拿过来的
    比如匿名、委托、还有刚才的创建对象……

    另外想问一下:
    通过这种url重写,把所有的aspx都重写成html
    实际上只是一种伪地址,真正访问的时候也还是aspx页面,这种做能提高搜索引擎收录率吗?还有应该不会对网站的性能有所提高吧?

  176. Eve[未注册用户]
    *.*.*.*
    链接

    Eve[未注册用户] 2008-06-13 19:39:00

    @ 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里也可以运行的。

  177. 老赵
    admin
    链接

    老赵 2008-06-14 01:49:00

    --引用--------------------------------------------------
    beafhorse: 昨天看老赵的asp.net ajax教程,有了思路.
    把usercontrol里面的script代码提取出来.放在页面的head中解析.

    这样是否可行?还有更好的办法没?
    --------------------------------------------------------
    则就是标准的做法了吧,当然不一定要放在head里,eval一下就行。

  178. 老赵
    admin
    链接

    老赵 2008-06-14 01:49:00

    --引用--------------------------------------------------
    beafhorse: 如果只考虑ie,加个defer就可以了.firefox有没有类似的标签?
    --------------------------------------------------------
    defer是标准,可惜firefox不支持

  179. 老赵
    admin
    链接

    老赵 2008-06-14 01:50:00

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

    另外想问一下:
    通过这种url重写,把所有的aspx都重写成html
    实际上只是一种伪地址,真正访问的时候也还是aspx页面,这种做能提高搜索引擎收录率吗?还有应该不会对网站的性能有所提高吧?
    --------------------------------------------------------
    其实新特性是参考动态语言的,不一定是JavaScript。
    至于url重写,把aspx写成html不会造成多大差别,也不会提高性能。

  180. 老赵
    admin
    链接

    老赵 2008-06-14 01:51:00

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

  181. brightwang
    *.*.*.*
    链接

    brightwang 2008-06-17 22:39:00

    我的做法是专门建个页面,然后把要输出的内容如(repeater)放在页面上,把body、html等无关的元素都去掉,然后代码绑定就可以直接输出到客户端,不知道你认为这中方式如何。

  182. 老赵
    admin
    链接

    老赵 2008-06-17 23:14:00

    --引用--------------------------------------------------
    brightwang: 我的做法是专门建个页面,然后把要输出的内容如(repeater)放在页面上,把body、html等无关的元素都去掉,然后代码绑定就可以直接输出到客户端,不知道你认为这中方式如何。
    --------------------------------------------------------
    效果一样

  183. beafhorse[未注册用户]
    *.*.*.*
    链接

    beafhorse[未注册用户] 2008-06-24 15:07:00

    --引用--------------------------------------------------
    希望回答: 麻烦问下 我的用户控件和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 .

  184. tsgtx[未注册用户]
    *.*.*.*
    链接

    tsgtx[未注册用户] 2008-07-03 08:03:00

    为什么不能用rendercontrol将用户控件转换成html串呢?
    别人已经做好的用户控件,我要怎么做才能把它转换成html串呢?

  185. tsgtx[未注册用户]
    *.*.*.*
    链接

    tsgtx[未注册用户] 2008-07-03 08:04:00

    为什么不能用rendercontrol将TabContainer及其它包含的控制转换成html串呢?

  186. willieQ
    *.*.*.*
    链接

    willieQ 2008-07-07 16:08:00

    website时,怎么定位用户控件类?
    ----对应代码--------
    ViewManager<ItemComments> viewManager = new ViewManager<ItemComments>();
    ======================

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

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

    不行

  187. 代码乱了
    *.*.*.*
    链接

    代码乱了 2008-07-13 23:05:00

    这个方法很不错,很实用

  188. singleblue
    *.*.*.*
    链接

    singleblue 2008-07-14 08:53:00

    这边的m_pageHolder,如果用Control来代替,效率是否能高一点点?

  189. 老赵
    admin
    链接

    老赵 2008-07-14 09:38:00

    @singleblue
    没法用Control的。

  190. matta[未注册用户]
    *.*.*.*
    链接

    matta[未注册用户] 2008-07-14 16:44:00

    其实比较贴切的说,是指你的
    HttpContext.Current.Server.Execute(this.m_pageHolder, output, false);

    其实不用这样的开销.

  191. 老赵
    admin
    链接

    老赵 2008-07-14 16:53:00

    @matta
    没看出有什么问题来

  192. matta[未注册用户]
    *.*.*.*
    链接

    matta[未注册用户] 2008-07-14 17:06:00

    一定要这样才行吗,没有更优的了?
    HttpContext.Current.Server.Execute(this.m_pageHolder, output, false);

  193. 老赵
    admin
    链接

    老赵 2008-07-14 20:25:00

    @matta
    不说优不优,没有觉得这个东西哪里差了阿,呵呵。

  194. clefoo
    *.*.*.*
    链接

    clefoo 2008-07-15 01:02:00

    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)

  195. 老赵
    admin
    链接

    老赵 2008-07-15 01:09:00

    @clefoo
    没看懂,你这个东西是做什么用的?

  196. clefoo
    *.*.*.*
    链接

    clefoo 2008-07-15 08:59:00

    @Jeffrey Zhao
    就是你的那个事例改了下。

    userControl生成html

  197. 老赵
    admin
    链接

    老赵 2008-07-15 11:51:00

    @clefoo
    能运行么?

  198. miao~
    *.*.*.*
    链接

    miao~ 2008-07-15 12:06:00

    有个问题,为什么我做的时候 点下一页的时候 如果
    <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)});
    }

    不知道其他的朋友有没有类似的问题?

  199. clefoo
    *.*.*.*
    链接

    clefoo 2008-07-15 12:49:00

    @miao~
    在href是要加上void(0);

    @Jeffrey Zhao
    可以运行

  200. miao~
    *.*.*.*
    链接

    miao~ 2008-07-15 13:10:00

    @clefoo
    但是老赵那个href 没有加 void(0) 啊....
    怎么能让它只执行 onClick 而保留 href 里的并不跳转呢?

  201. 老赵
    admin
    链接

    老赵 2008-07-15 13:13:00

    @miao~
    看我的js是怎么写的

  202. miao~
    *.*.*.*
    链接

    miao~ 2008-07-15 13:20:00

    @Jeffrey Zhao
    非常感谢,少加了
    return false; // IE only


  203. 陈招展
    *.*.*.*
    链接

    陈招展 2008-07-17 00:33:00

    这么多评论啊…

  204. Fanty
    *.*.*.*
    链接

    Fanty 2008-07-21 12:57:00

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

  205. 老赵
    admin
    链接

    老赵 2008-07-21 14:01:00

    @Fanty
    不是bug,上面的评论就讲过解决方法,你这个做法太复杂了。

  206. Fanty
    *.*.*.*
    链接

    Fanty 2008-07-21 19:28:00

    @Jeffrey Zhao
    对不起,我没有看见上面的哪有更好的解决方案!
    不过您当时的这种做法给了我很大的构想!令我可以想到2008 MVC下去进行该模式的设计!并且省下要建立ashx的麻烦

  207. 老赵
    admin
    链接

    老赵 2008-07-21 21:46:00

    @Fanty
    不直接使用Page,而是使用Page的自定义子类,把VerifyXxxx方法给override掉即可。

  208. 淡淡的[未注册用户]
    *.*.*.*
    链接

    淡淡的[未注册用户] 2008-08-28 15:04:00

    程序发出来了,楼主,福利大家

  209. 淡淡的[未注册用户]
    *.*.*.*
    链接

    淡淡的[未注册用户] 2008-08-28 15:05:00

    楼主多做视频呀。哇哇

  210. tc11o8
    *.*.*.*
    链接

    tc11o8 2008-09-11 18:05:00

    老赵,你能把这个例子能提供下载或者给我邮箱发一份吗
    我的邮箱:zmj119@hotmail.com

  211. 窜天下[未注册用户]
    *.*.*.*
    链接

    窜天下[未注册用户] 2008-09-15 09:40:00

    这段代码是什么意思:


    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,麻烦解释一下,我运行不了

  212. 窜天下[未注册用户]
    *.*.*.*
    链接

    窜天下[未注册用户] 2008-09-15 09:41:00

    笔误多了一点啊,呵呵

  213. 窜天下[未注册用户]
    *.*.*.*
    链接

    窜天下[未注册用户] 2008-09-15 09:47:00

    你能给我也发一份吧,我的邮箱是levinyang@gmail.com,我研究研究.

  214. tc11o8
    *.*.*.*
    链接

    tc11o8 2008-09-18 11:54:00

    我觉得 用usercontrol 来做html生成 有一些问题
    这样会带来臃于数据的返回 控件中的一些无用的脚本 标签等也都被重复返回到了客户端 这样的做法实现类似于updatepanel 与服务器交互中 数据的传输量丝毫没有减少 还是传统的把整个页面返回到客户端 对网络带宽就得有一定要求了
    我觉得web程序还是最好把有用的数据来进行传输 将数据进行定义成某一格式 比如json,xml等 这样就能带来web服务器数据的复用 虽然开发上可能会复杂一些 但这样实现了松耦合 可以多人开发这个程序 一个做页面处理 一个做服务端开发 彼此可以独立的进行开发 只要他们定义好数据交互的格式就行

  215. 老赵
    admin
    链接

    老赵 2008-09-21 13:18:00

    @tc11o8
    文章说了这种做法有利有弊的

  216. tc11o8
    *.*.*.*
    链接

    tc11o8 2008-09-21 15:00:00

    谢谢 楼主 我也常看你的视频教程 :)

  217. gjj[未注册用户]
    *.*.*.*
    链接

    gjj[未注册用户] 2008-10-30 15:16:00

    ViewManager<ItemComments> viewManager = new ViewManager<ItemComments>();
    itemComments
    ItemComments是不能引用出来的

  218. 小涂[未注册用户]
    *.*.*.*
    链接

    小涂[未注册用户] 2008-10-31 12:57:00

    博主 你好 看了你的文章很感兴趣,
    但我技术比较差 看的不是很明白
    我想问一下 这个用户控件做HTML生成有没有例子,能不能发个给我研究一下,我现在用到了这个 很想了解 学会 谢谢了 有的话发个到我邮箱给我 真的感谢

  219. nick_temp[未注册用户]
    *.*.*.*
    链接

    nick_temp[未注册用户] 2008-12-27 02:28:00

    //老赵:如果加载的用户控件用了缓存的话,是存在问题的。
    //我在网上找了一些资料,但还是没有解决问题
    //((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();
    }
    }

  220. fengO[未注册用户]
    *.*.*.*
    链接

    fengO[未注册用户] 2009-01-16 10:13:00

    我把代码放在了Web服务的后置代码文件中,再现了下面的错误,

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

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

    如果放在一个.asmx文件中就可以,不知道其它人有没有这样的事情发生过,有没有什么解决方法?

  221. renshivs[未注册用户]
    *.*.*.*
    链接

    renshivs[未注册用户] 2009-02-06 17:03:00

    --引用--------------------------------------------------
    gjj: ViewManager&lt;ItemComments&gt; viewManager = new ViewManager&lt;ItemComments&gt;();
    itemComments
    ItemComments是不能引用出来的

    --------------------------------------------------------
    我也无法引用,不知道赵老师能不能解答下?

  222. zachary[未注册用户]
    *.*.*.*
    链接

    zachary[未注册用户] 2009-03-10 13:49:00

    你好,老赵
    看了你的代码自己也在项目中想用一把
    结果却是在HttpHandler类里动态加载ascx时候报编译错:找不到类型或命名空间名称
    我用的是2005开发的,能不能将你的代码发我一份,让我研究学习一下呢
    我的邮箱地址:zachary.woo@163.com

  223. 彭白洋
    *.*.*.*
    链接

    彭白洋 2009-03-30 18:35:00

    楼主,您好!问个低级的问题啊:嘿嘿

    这事您的代码:

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

    这个地方小弟很迷惑 谢谢楼主解答……

  224. 老赵
    admin
    链接

    老赵 2009-03-30 20:10:00

    @彭白洋
    1、真可以吗?
    2、参数如何设置?

  225. 彭白洋
    *.*.*.*
    链接

    彭白洋 2009-03-31 13:03:00

    我用的 vs2008 .net3.5
    是可以的
    不用定义一个容器 重新加载一下控件的


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


    Execute有一个这样的 重载方法的

  226. 老赵
    admin
    链接

    老赵 2009-03-31 15:20:00

    @彭白洋
    参数可以设置吗?

  227. 邢少
    *.*.*.*
    链接

    邢少 2009-09-14 10:01:00

    不错.··!一个心得思路。非常好.哈哈.虽然大概是我想的生成过程。但是在具体实现上很简单,但是很精简。学习!

  228. 蛙蛙王子
    *.*.*.*
    链接

    蛙蛙王子 2009-09-24 13:16:00

    才看到,不错,再看看老赵其它的老贴子。

  229. 寻自己
    *.*.*.*
    链接

    寻自己 2009-10-27 13:50:00

    StringWriter sw = new StringWriter();
    HtmlTextWriter htw = new HtmlTextWriter(sw);
    Repeater rpt = new Repeater();
    rpt.DataSource = Comment.GetComments(PageSize,PageIndex,out m_totalCount);
    rpt.DataBind();
    rpt.RenderControl(htw);
    return sw.ToString();

    这个也可以吧,赵老师?
    ----------------------
    忘记看前面的了,原来这个不符合DRY原则

  230. hailibu
    *.*.*.*
    链接

    hailibu 2009-11-03 14:53:00

    老赵,你好!
    public class ViewManager<T> where T : UserControl 可不可以改成
    public class ViewManager<T> where T : Page

    因为我想用 aspx页面 来生成html,请指教:)

  231. 老赵
    admin
    链接

    老赵 2009-11-03 14:57:00

    @hailibu
    我不知道,你试一下吧。
    不过我不明白,既然生成HTML片段,为什么要用Page啊。

  232. hailibu
    *.*.*.*
    链接

    hailibu 2009-11-03 15:26:00

    老赵响应处理真是快,感动ing

    我刚才试过了,不行啊 :(

    错误提示:类型“ASP.test_aspx”不从“System.Web.UI.UserControl”继承

    return (T)this.m_pageHolder.LoadControl(path);//这句打红色标识

    PS:我想通过 读取动态页面上的HTML 来生成 一个静态页面文件。


  233. 老赵
    admin
    链接

    老赵 2009-11-18 23:17:00

    @Anoxia
    用评论的代码插入功能吧。

  234. 老赵
    admin
    链接

    老赵 2009-11-18 23:18:00

    @hailibu
    Server.Execute,你可以使用这个。

  235. Frank.K[未注册用户]
    *.*.*.*
    链接

    Frank.K[未注册用户] 2009-11-18 23:37:00

    老赵您好,我利用这种方法做例子时候碰到一个问题,我在usercontrol中使用了Repeater控件,但是我在Repeater的databind事件中需要做一些相应的处理,实际运行后发现这样的方式并不会激发控件事件,所以我无法在该事件中进行必要的数据处理,请问这种情况有什么办法可以解决???

  236. Anoxia
    *.*.*.*
    链接

    Anoxia 2009-11-18 23:46:00

    @Jeffrey Zhao
    页面通过ajax调用ManageWS(WEBSERVICE)里的loadMenuList方法,加载usercontrol中的数据,为了实现页面中点击某个TAB后动态加载左侧的菜单,此菜单部分是个usercontrol。但是这么做了之后usercontrol中的onitemcommand事件没有触发,实在没办法了,请赵老师指点。代码片段如下:

    usercontrol中代码片段:

    <asp:Repeater ID="rootRp" runat="server" onitemcommand="rootRp_ItemCommand" >
        <ItemTemplate>
            <h2>
                <asp:Label ID="rootName" runat="server" Text='<%#Eval("Name") %>'></asp:Label>
            </h2>
            
            <asp:Repeater ID="menuRp" runat="server">
                <HeaderTemplate>
                    <ul>
                </HeaderTemplate>
                <ItemTemplate>
                    <li>&raquo;&nbsp;
                        <a href='<%#Eval("url") %>' title='<%#Eval("Name") %>'><%#Eval("Name") %></a>
                      
                    </li>
                </ItemTemplate>
                <FooterTemplate>
                    </ul>
                </FooterTemplate>
            </asp:Repeater>
        </ItemTemplate>
    </asp:Repeater>
    


    ManageWS.asmx.cs代码片段:

    [WebMethod(EnableSession = true)]
            public string loadMenuList(string tabId) {
                try {
                    TM.Dealer.Common.ViewManager<menuBack> menuBack = new TM.Dealer.Common.ViewManager<menuBack>();
                    var control = menuBack.loadViewControl("~/manage/usercontrols/menuBack.ascx");
                    control.Id = Convert.ToInt32(tabId);
                    var s = menuBack.RenderView(control);
                    return s;
                }
                catch (Exception ex)
                {
                    return "调用Web服务失败,错误原因:<br/>" + ex.Message;
                }
            }
    


    ViewManager代码片段:

    public class ViewManager<T> where T : UserControl //此处用范型限定了该类只适用于usercontrol
        {
            private Page p;
    
            /// <summary>
            /// 加载用户控件
            /// </summary>
            /// <param name="path"></param>
            /// <returns></returns>
            public T loadViewControl(string path)
            {
                this.p = new MyPage();
                return  p.LoadControl(path) as T;
            }
         
            /// <summary>
            /// 呈现控件内容
            /// </summary>
            /// <param name="control"></param>
            /// <returns></returns>
            public string RenderView(T control)
            {
                StringWriter output = new StringWriter();
    
                this.p.Controls.Add(control);
                System.Web.HttpContext.Current.Server.Execute(this.p, output, false);
                return output.ToString();
            }
    
            //该类用来重写VerifyRenderingInServerForm方法,该方法的控制对呈现服务端控件有很大的影响
            public class MyPage : Page
            {
                public override void VerifyRenderingInServerForm(Control control)
                {
                                    
                    //base.VerifyRenderingInServerForm(control);
                }
            }
        }
    


  237. 老赵
    admin
    链接

    老赵 2009-11-19 00:05:00

    @Frank.K
    首先,这样的控件最好不要有复杂的功能,其次,你就这样做吧:
    http://www.cnblogs.com/JeffreyZhao/archive/2009/10/14/about-debugging.html

  238. 老赵
    admin
    链接

    老赵 2009-11-19 00:06:00

    @Anoxia
    明天有空了看看。:)

  239. Frank.K[未注册用户]
    *.*.*.*
    链接

    Frank.K[未注册用户] 2009-11-19 00:16:00

    好的,先谢过,这篇文章我会好好看看的,再次感谢。。。

  240. Anoxia
    *.*.*.*
    链接

    Anoxia 2009-11-19 01:16:00

    @Jeffrey Zhao
    最后用了极丑陋的方式实现了,还是期待赵老师找到好点的解决方案。我将Repeater的onitemdatabound事件去掉了,在Repeater里循环输出JS回调WebService输出string。
    哎,代码片段如下:


    <asp:Repeater ID="rootRp" runat="server" ><%--onitemcommand="rootRp_ItemCommand"--%>
        <ItemTemplate>
            <h2>
                <asp:Label ID="rootName" runat="server" Text='<%#Eval("Name") %>'></asp:Label>
            </h2>
            <ul id='<%#String.Format("menuUl{0}",Eval("MenuId")) %>'>
                
            </ul>
            <script type="text/javascript">
                 $('<%#String.Format("#menuUl{0}",Eval("MenuId")) %>').load("ajaxHelp.aspx", function(result) {
                    //设置loading进度
                    $('<%#String.Format("#menuUl{0}",Eval("MenuId")) %>').html("从服务端获取数据中,请稍候...");
                    //调用WS
                    TMDealerPro.manage.WebService.ManageWS.loadChildMenuList('<%#Eval("MenuId")%>', 
                        function(result){
                            $('<%#String.Format("#menuUl{0}",Eval("MenuId")) %>').fadeIn("slow", function() {
                            $(this).html(result);
                        });
                    });
                }); 
                      </script>
              </ItemTemplate>
    </asp:Repeater>
    
    

  241. 老赵
    admin
    链接

    老赵 2009-11-19 09:04:00

    @Anoxia
    岂不是很慢?

  242. Anoxia
    *.*.*.*
    链接

    Anoxia 2009-11-19 09:47:00

    @Jeffrey Zhao
    看你这贴心动就想用,但感觉在具体这个业务逻辑上这么用反而化简为繁了,呵呵。用通常的做法,套UpdatePanel服务端控制呈现很简单的。不过,这种情况下,赵老师如果有new idea,期待中...

  243. 老赵
    admin
    链接

    老赵 2009-11-19 23:16:00

    @Anoxia
    为什么要触发onitemcommand?
    其实这个方法只是用来生成HTML的,不是用来做前后台交互的……

  244. 俊采星驰
    *.*.*.*
    链接

    俊采星驰 2009-12-27 20:51:00

    请问楼主我按照你给的代码试了下没加AJAX前没有问题,但加了之后点击下一页时数据还是原来的那些没有改变。我打断点调试时后台代码也是已经执行了的,而且也重新绑定了ItemComments.ascx控件,但在前台就是没法更新。请楼主指点迷津~~

  245. 俊采星驰
    *.*.*.*
    链接

    俊采星驰 2009-12-27 21:03:00

    看了评论才知道原来忘记给div加id了,还以为id是没用的呢,真是郁闷了我半天!!

  246. e狐
    *.*.*.*
    链接

    e狐 2009-12-27 23:22:00

    赵老师,请教个问题。。你上面的例子中GetComments这个Handler中
    ViewManager<ItemComments> viewManager = new ViewManager<ItemComments>();
    ItemComments control = viewManager.LoadViewControl("~/ItemComments.ascx");

    这个里面的ItemComments 类型是怎么引用到的??我试过都放在一个命名空间里面也引用不到啊。。

  247. e狐
    *.*.*.*
    链接

    e狐 2009-12-27 23:33:00

    是不是上面的代码仅仅是个例子啊?我是不是一定能够要建个ClassLibrary放入ItemComments的后台实现与GetComments,然后用站点引用这个ClassLibray才行啊?

  248. 老赵
    admin
    链接

    老赵 2009-12-27 23:46:00

    @e狐
    总之,你引用到就行了——这个是ASP.NET基础吧……

  249. 伊牛娃
    *.*.*.*
    链接

    伊牛娃 2010-03-15 11:32:00

    ItemComments.aspx
    应该是ItemComments.ascx

  250. 无尽的天空
    121.33.97.*
    链接

    无尽的天空 2010-07-05 14:56:28

    写的不错 !!不过没有看太懂哦 !!!能不能给我一份源码!!试一下效果!!感谢 !!!

    zhsong_1989@foxmal.com

  251. lorgine
    202.136.217.*
    链接

    lorgine 2010-12-24 13:29:40

    这个代码很令人激动。

  252. bugship
    116.228.220.*
    链接

    bugship 2011-01-25 17:46:36

    这种方式的确很实用,开发效率快,但会多出来不少.ashx文件。如何合理安排安些.ashx,有什么好的方法; 谢谢

发表回复

登录 / 登录并记住我 ,登陆后便可删除或修改已发表的评论 (请注意保留评论内容)

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

评论内容(大于5个字符):

  1. Your Name yyyy-MM-dd HH:mm:ss

使用Live Messenger联系我