views:

525

answers:

4

Currently I'm registering every user control separately in 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>

But from time to time I forget to checkin web.config. Actually, I usually forget that it have changed skip it because it often breaks settings others set to connect to their local db DB copy.

I was wondering is it possible to just specify whole Controls directory and get all controls there registered automatically

+1  A: 

That's not possible in web.config, so far as I know. There are a couple workarounds... one would be put your controls in a separate project and compile them into a single assembly that gets referenced in web.config.

Personally, I like to skip the web.config registration and just register them in whatever page is using the controls. That would avoid the problem of breaking other developer's web.config.

Bryan
+2  A: 

Yes and no.

Basically, you can registers all your usecontrols in the web.config. BUT, you'll run into problems if you want to use any of your usercontrols within other usercontrols.

So, if you're never going to nest usercontrols, you're good to go. BUT, if you want the flexibility to nest usercontrols you've got a few options:

  1. Register them all in the web.config, and then in the case of nesting, resgister the control you're nesting directly in the usecontrol
  2. As Bryan mentioned above, compile your usercontrols into an assembly, and reference them in the web.config
  3. This is the worst option, but basically you can get around the nesting problem when registering all your usercontrols in the web.config by placing your controls in sub folders...not a great option.
  4. Another option is to strongly type your usecontrols, perhaps by creating base classes for your usercontrols.

Basically its not a bug in the framework, but a result of compiling everything into a single assembly. The app essentially can''t distinguish between user controls

there's some more info here and here. check out the comments on this one

andy
Thanks, that's pretty cool. I will probably go creating a project Web and separate project Web.Controls next time I start new project
Sergej Andrejev
cool, I'll be interested to know if it works, and how easy it is to implement. good luck!
andy
+1  A: 

Generate your Web.Config from Global.asax:

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

}

... and all of your entries will appear in web.config.

Jeff Fritz
A: 

Here's a VB.NET adaptation of @Jeff Fritz's solution. It does the same thing but includes all controls located anywhere in the solution. (Our architecture uses modules that can be incorporated as SVN externals, so this provides a very nice way to make sure that the host application is aware of all modules' controls.)

    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

(Of course you would reference this in Application_Start like Jeff did.)

Herb Caudill