Introduction
Having to deal with a multi-developer solution, I face the problem of structuring my web app in a hierarchy. As an ASP guy, I was used to put all common stuff in the root directory (or in an include directory) and then all the site parts in subdirectories.
A structure like this:
RootWeb
-- SubWeb1
----SubSubWeb1
----SubSubWeb2
-- SubWeb2
.... you got the idea.
Developing in this manner with VS.NET (2003) isn't easily possible, but with some work, you can get very close. A disclaimer about this article: I didn't use it in a real software farm, but I'm starting soon. Hopefully, I'll get some hint or correction from readers! So, let's start....
The idea is to create the hierarchical structure of your web project, and in the build phase, copy all the assembly in the root's bin directory. Create a directory for the web project (C:\Projects\RootWeb). In IIS MMC, create the corresponding virtual directory. I created on "Default Web Site" a virtual directory named RootWeb (New->Virtual Directory->Next->Alias="RootWeb"-> Directory="C:\Projects\RootWeb"->leave default permissions). You have to configure FrontPage server extension for the virtual directory.
Trick 1
At least for W2K, there isn't a menu entry for configuring FPSE on the IIS MMC you used so far. Close the MMC, and reopen it. Right clicking on RootWeb virtual directory, you see on "All Tasks", an entry "Configure Server Extension". Leave all default options.
Now on VS.NET: Create a blank solution named RootWeb in C:\Projects\RootWeb. Create a new project on it: New Project->Visual C# Projects->ASP.NET Web Application->Location="http://localhost/RootWeb". Create a new project: New Project->Visual C# Projects->ASP.NET Web Application->Location="http://localhost/RootWeb/SubWeb1".
The default web project is created with FrontPage Access. You have to convert the project for using file share. This way you can use VSS integration easily. Once converted, just use Add Project to Source Control.
Beware that you have to configure FrontPage extension on the server, also if you're going to use file share.
If you (or another developer) want to use the same project on another computer, you have to go to File menu->Source control->Add project from source control.
In C# projects, you can use post build events. In VS.NET IDE, you can't specify the post build script from the IDE for web applications, but you can definitely set it in the .csproj file.
Trick 2
Open the .csproj file (C:\Projects\RootWeb\SubWeb1\SubWeb1.csproj) and specify the value for PostBuildEvent
. In our case, we simply copy the generated assembly to the root's bin directory, so something like: PostBuildEvent = "move $(TargetDir)$(TargetFileName) C:\Projects\RootWeb\bin\"
.
Trick 3
If the TargetDir
contains spaces, the copy command will fail (is the usual DOS copy command). As you know, you can solve this by specifying the path in double quotes. But the .csproj is an XML file, so if you put double quotes, it will mess up. So, we change the attribute delimiter from double quote to single quote (replace all " with ' using your favorite editor). This .csproj remains a well formed XML file, and we can put the double quote around our path: PostBuildEvent = 'move "$(TargetDir)$(TargetFileName)" C:\Projects\RootWeb\bin\'
.
You have also to delete the global.asax* and web.config files in subprojects, and delete the related entry from the .csproj file.
Note: maybe you'd like to change DefaultHTMLPageLayout
to flow
for HTML compatibility. Every new webform created will have this setting. To change the automatically created WebForm1.aspx also, delete the string >MS_POSITIONING="GridLayout"
<, or do it from the IDE.
Write something useful in WebForm1.aspx of the RootWeb (Like "Hello World from the Root web"). Write something useful in WebForm1.aspx of the RootWeb\Sub1 (Like "Hello World from the sub web 1"). Now, you're ready to build the solution and test it at http://localhost/RootWeb/webform1.aspx and http://localhost/RootWeb/SubWeb1/webform1.aspx. If you create an ascx on the root web, you can use it in every descendant web, just by drag 'n dropping it in web forms. Also, the context of the web application is the same in all descendant web folders.
Improvements
Doing this is tedious, and you have to tell every developer how to do it. Enterprise templates come to rescue. Defining a new template with all this stuff on it will ease the problem. (See the tutorial at MSDN). It will be better if the destination directory is automatically parameterized on the root directory path. Organizing the web in this way could cause some duplicate names. You'd better name the namespaces accordingly to the directory structure. For the RootWeb\Sub1\WebForm1.aspx, you have to specify:
namespace RootWeb.SubWeb1
Conclusion
Acting this way lets you organize the web application in a hierarchical fashion.
The solution presented here is complex, and maybe in next releases of VS.NET, it will be difficult or impossible to port.
Maybe someone has an idea if next releases of VS.NET (Whidbey) will support natively this organization..... let me know.