asp.net usercontrol vs customcontrol vs stringbuilder

时间:2010-12-22 19:22:24

标签: asp.net user-controls custom-controls stringbuilder

我正在构建一个产品目录,每页显示50/100个产品。 由于我想在我的网站上有不同的浏览部分,我已经放了每个产品 进入UserControl。好吧,不是产品本身的当然,而是一些标签,divs 和图像。然后,我在处理数据库结果时在运行时设置其属性。所以优点是我只需要在整个站点的1个地方更改产品控制。我正在循环中使用LoadControl将控件放在页面中。

然而,页面的加载速度并不像处理相同db查询并使用StringBuilder输出相同html的其他页面一样快。而且,由于我希望我的网站在收到一些不错的流量时表现良好,我很担心这一点。我还没有做过任何基准测试,但我清楚地看到了差异。

我的问题够了!我向您提出的问题是“有没有其他方法比使用带有自定义控件的LoadControl更快,但很容易维护(或至少在1个位置)?”

我在考虑:

  1. 创建一个自定义控件(虽然我从来没有这样做过,如果这会加快速度,就不知道100%)
  2. 继续使用StringBuilder方法并将CreateProduct放在我的基类
  3. 放弃将产品保存在一个位置的整个想法
  4. 我希望你们有类似的情况选择,所以我真的很想听听你们的意见!

    [编辑]代码[/编辑] 我在这里没有精确的usercontrol代码,但是当我回到家时我会编辑这篇文章。但这里是简化的想法:

    1)获取我的数据库结果(使用Subsonic 2.2作为我的DAL)

    DAL.ProductCollection coll = new DAL.ProductCollection();
    if(coll.count > 0)
    {
       foreach(DAL.Product item in coll)
       {
         Control p = LoadControl("FeaturedProduct.ascx");
         placeholder.Controls.Add(p);
    
         //Set properties
         p.title = item.Title;
         p.img = GetImage(item.Guid);
         ....etc
       }
    }
    

    我的用户控件本身只包含3个Literal控件和1个Image控件。

    但是当我到家时我会发布完整的代码! 感谢

4 个答案:

答案 0 :(得分:2)

您是否尝试在Viewstate中关闭UserControl?如果您使用StringBuilder构建标记,则不会为任何标记来回传输任何Viewstate。如果您使用默认的ASP Web控件,它们将默认为Viewstate,它将在页面加载和回发期间来回传输,并且可能非常大,具体取决于UserControl中使用的Web控件并重复50到100次。

修改:如果Viewstate不是问题,您是否确认UserControl生成的标记与您在StringBuilder中生成的标记相同或相当等效?

另一个关键的事情是对服务器和客户端时间进行基准测试。如果标记不同,则客户端呈现时间可能会发生显着变化。如果服务器和客户端的时间相同(或微不足道),那么您需要查看服务器输出的大小和传输时间。

答案 1 :(得分:2)

假设您有数据库查询的产品列表List<Product>。您可以将Repeater控件绑定到该列表,然后在标记中添加转发器中的UserControl。

以下是一个示例,其中包含类Product:

class Product{ public string Sku{ get; set; } public string Name{ get; set; } }

在你的标记中声明:

<asp:Repeater runat="server" ID="ProductsRepeater" >
    <ItemTemplate>
        <uc1:ProductsUserControl runat="server" ID="productsControl" Sku='<%# Eval("Sku")%>' Name='<%# Eval("Name") %>'/>
    </ItemTemplate>
</asp:Repeater>

然后在你的代码背后:

protected void Page_Load(object sender, EventArgs 
{
    ProductsRepeater.DataSource = myProductsList;
    ProductsRepeater.DataBind();
}

这将在您的产品列表中为每个记录添加1个用户控件,并将Property对象的Sku和Name属性绑定到用户控件上的相应属性。

如果这还不够快,也许你的用户控件有点时髦吗?

答案 2 :(得分:1)

UserControl听起来像是您正在做的事情的高质量解决方案。不要放弃这个想法。抽象让世界四处流传。

我已经要求您显示您的UserControl标记了。此外,除非您在后面的代码中构建所有内容,否则不需要使用LoadControl()

答案 3 :(得分:1)

我将切换到使用ASP.NET服务器控件并覆盖它的Render方法。这与您的StringBuilder解决方案更相似,因为您可以使用提供给该方法的HtmlTextWriter来构建HTML输出,类似于使用字符串生成器的方式。但同时你得到了控制结构,这使你能够添加属性,管理状态等。由于编译了服务器控件,我认为它通常比用户控件执行得更好。

我还会创建另一个服务器控件,它是一个用于构建控件列表的容器。不确定这会更高效,但这是一个很好的做法,会使您的代码更容易重用和维护。