在Web.config中是否可以在指定目录中注册所有用户控件

时间:2009-03-25 07:14:34

标签: asp.net user-controls web-config

目前我正在Web.config

中单独注册每个用户控件
<pages validateRequest="false">
  <controls>
    <add tagPrefix="cc1" src="~/Controls/MyUserControl1.ascx" tagName="MyUserControl1"/>
    ...    
    <add tagPrefix="cc1" src="~/Controls/MyUserControlN.ascx" tagName="MyUserControlN"/>
  </controls>
</pages>

但我不时忘记检查web.config。实际上,我经常忘记它已更改跳过它,因为它经常会破坏其他设置为连接到本地db DB副本的设置。

我想知道是否可以只指定整个Controls目录并自动注册所有控件

4 个答案:

答案 0 :(得分:8)

是和否。

基本上,您可以在web.config中注册所有用户控件。但是如果你想在其他用户控件中使用任何用户控件,你会遇到问题。

所以,如果你永远不会嵌套用户控件,那么你很高兴。但是如果你想要灵活地嵌套用户控件,你有几个选择:

  1. 在web.config中注册所有内容,然后,在嵌套的情况下,将您直接嵌套的控件注册到父用户控件中。
  2. 正如上面提到的Bryan,将您的usercontrol编译成一个程序集,并在web.config中引用它们。
  3. 这是最糟糕的选择,但基本上你可以通过将控件放在子文件夹中来注册web.config中的所有用户控件来解决嵌套问题...这不是一个很好的选择。
  4. 另一个选择是强烈地键入你的用户控件,可能是通过为你的用户控件创建基类。
  5. 基本上,它不是框架中的错误,而是将所有内容编译到单个程序集中的结果。该应用程序基本上无法区分用户控件。

    还有一些信息herehere. check out the comments on this one

答案 1 :(得分:1)

据我所知,这在web.config中是不可能的。有几种解决方法......一种是将控件放在一个单独的项目中,并将它们编译成一个在web.config中引用的程序集。

就个人而言,我喜欢跳过web.config注册,只是在使用控件的任何页面中注册它们。这样可以避免破坏其他开发人员的web.config。

答案 2 :(得分:1)

从Global.asax生成您的Web.Config:

protected void Application_Start(object sender, EventArgs e)
{

    Configuration config = WebConfigurationManager.OpenWebConfiguration("~/");
    PagesSection webSection = config.GetSection("system.web/pages") as PagesSection;

    List<TagPrefixInfo> toRemove = new List<TagPrefixInfo>();
    foreach (TagPrefixInfo info in webSection.Controls)
    {
        if (info.TagPrefix != "asp")
            toRemove.Add(info);
    }

    foreach (TagPrefixInfo list in toRemove)
    {
        webSection.Controls.Remove(list);
    }

    DirectoryInfo di = new DirectoryInfo(Server.MapPath("~/Controls"));
    foreach (FileInfo file in di.GetFiles("*.ascx"))
    {
        TagPrefixInfo newtag = new TagPrefixInfo("PREFIX", null, null, file.Name.Replace(".ascx",""), string.Concat("~/Controls/", file.Name));
        webSection.Controls.Add(newtag);

    }

    config.Save(ConfigurationSaveMode.Modified);
    ConfigurationManager.RefreshSection("system.web/pages");

}

...并且所有条目都将显示在web.config中。

答案 3 :(得分:0)

这是@Jeff Fritz解决方案的VB.NET改编版。它做同样的事情,但包括位于解决方案中任何位置的所有控件。 (我们的架构使用可以作为SVN外部结构的模块,因此这提供了一种非常好的方法来确保主机应用程序知道所有模块的控件。)

    Sub RegisterUserControls()
        Dim Config As Configuration = WebConfigurationManager.OpenWebConfiguration("~/")
        Dim WebSection As PagesSection = TryCast(Config.GetSection("system.web/pages"), PagesSection)
        Dim ToRemove As List(Of TagPrefixInfo) = ( _
                From t As TagPrefixInfo In WebSection.Controls _
                Select t Where t.Source IsNot Nothing AndAlso t.Source.EndsWith(".ascx") _
            ).ToList
        For Each t As TagPrefixInfo In ToRemove
            WebSection.Controls.Remove(t)
        Next
        Dim SiteRoot As New DirectoryInfo(Server.MapPath("~"))
        For Each f As FileInfo In SiteRoot.GetFiles("*.ascx", SearchOption.AllDirectories)
            Dim Source As String = Path.Combine("~/", f.FullName.Replace(SiteRoot.FullName, "")).Replace("\", "/")
            Dim TagName As String = Path.GetFileNameWithoutExtension(f.Name)
            Dim NewTag As New TagPrefixInfo( _
                tagPrefix:="YOURPREFIX", _
                nameSpace:=Nothing, _
                assembly:=Nothing, _
                TagName:=TagName, _
                Source:=Source)
            WebSection.Controls.Add(NewTag)
        Next
        Config.Save(ConfigurationSaveMode.Modified)
        ConfigurationManager.RefreshSection("system.web/pages")
    End Sub

(当然你会像Jeff那样在Application_Start中引用它。)