【问题标题】:asp.net usercontrol vs customcontrol vs stringbuilderasp.net usercontrol vs customcontrol vs stringbuilder
【发布时间】:2011-05-29 14:39:18
【问题描述】:

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

但是,这些页面的加载速度不如处理相同数据库查询并使用 StringBuilder 输出相同 html 的其他页面那么快。而且由于我希望我的网站在收到一些不错的流量时表现良好,我对此感到担心。我还没有进行任何基准测试,但我清楚地看到了差异。

我的问题已经够多了!我的问题是“有没有比使用带有自定义控件的 LoadControl 更快但易于维护(或至少在 1 个位置)的替代方法?”

我在想:

  1. 创建自定义控件(虽然我从未做过,也不知道 100% 是否会加快速度)
  2. 继续使用 StringBuilder 方法并将 CreateProduct 放入我的基类中
  3. 放弃在 1 个位置维护产品的整个想法

我希望你们有类似的情况选择,所以我真的很想听听你们的意见!

[编辑]代码[/编辑] 我这里没有确切的用户控制代码,但我回家后会编辑这篇文章..但这里是简化的想法:

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 个文字控件和 1 个图像控件。

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

【问题讨论】:

  • 你能发布一些你的 html 输出吗?和你的产品UserControl?当你打电话给LoadControl()

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


【解决方案1】:

假设您有一个产品列表List<Product> 作为数据库查询的结果。您可以将Repeater 控件绑定到该列表,然后在您的标记中将UserControl 添加到repeater 中。

这是一个示例,产品类如图所示:

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 属性绑定到用户控件上的相应属性。

如果这还不够快,可能是您的用户控件有问题?

【讨论】:

  • 嗨,格雷格,感谢您的建议。我也考虑过这个解决方案,但我认为中继器也在后台使用 LoadControl。我想!但我会检查一下,谢谢
  • @Mark:可能,我不太确定。告诉我你发现了什么。
【解决方案2】:

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

编辑:如果Viewstate 不是问题,您是否验证了UserControl 生成的标记与您在StringBuilder 中生成的标记相同或相当等价?

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

【讨论】:

  • 是的,网站大部分区域的视图状态已关闭。虽然它不是很慢,但显然比 stringbuilder 慢。也许我只是偏执,需要一台更快的电脑。
【解决方案3】:

UserControl 听起来像是您正在做的事情的优质解决方案。不要放弃这个想法。抽象使世界运转。

我已要求您显示您的 UserControl 标记。此外,您不需要使用LoadControl(),除非您在后面的代码中构建这一切。

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-16
      • 1970-01-01
      • 2015-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-29
      相关资源
      最近更新 更多