是否有可能让经典的asp.net动态加载声明的webcontrols的子类型

时间:2012-02-03 11:47:21

标签: asp.net user-controls webforms web-controls multi-tenant

我希望能够以标准方式声明性地指定任何给定页面的webcontrol,但是使运行时不一定是我指定的类型的新实例,而是例如检查web.config是否应该使用不同的webcontrol(将从指定的继承)。

例如,我可以在路径/templates/controls/default/PersonSelector.ascx中使用webcontrol,在路径/templates/controls/CUSTOMER_A/PersonSelector.ascx中继承另一个(继承自第一个)

所以,如果我的配置表明我更喜欢从可用的CUSTOMER_A文件夹加载控件,并且因为在这种情况下它可用,那么用于页面的实际标记将来自... / CUSTOMER_A / PersonSelector.ascx。编译时假设它实际上是../default/PersonSelector.ascx实例的所有代码仍然可以工作,因为它实际上是一个子类。

这对我们的网站来说是一个重要的好处,这是一个多租户网站,其中99.5%生成的html在我们所有客户中都是相同的(除了皮肤,自然除外),但一些客户需要不同的页眉/页脚/选择逻辑等。到目前为止,所有差异都是通过膨胀控件和if / else-ing来处理的。

我意识到asp.net可能不是做这种事情的首选武器,但它是我们得到的,并且代码库足够大,重写会很痛苦。

1 个答案:

答案 0 :(得分:1)

是的,您可以使用LoadControl method动态加载用户控件。如果您有Control1Control2Control2继承自Control1,您可以在页面中执行此操作:

//Obtain control name in the format "~/pathFromApplicationRoot/ControlName.ascx"
string controlName = MethodThatDecidesTheControlNameToLoad();
//Load control
var userControl = (Control1)this.LoadControl(controlName);
//Add it to page
AControlSuchAsAPlaceHolder.Controls.Add(userControl);

修改 为了能够在标记中以声明方式指定用户控件,我猜你可以让用户控件用租户特定的控件替换它自己的内容,如果配置告诉它要覆盖它。