Lately I have been writing a lot of code utilizing the Microsoft Ajax framework. This means that I am writing “Ajax Services” to handle my asynchronous callbacks. Ajax Services is a term I heard from Rob Bagby which emphasizes the fact that while these services are generally in a .asmx file and the methods are decorated with the [WebMethod] attribute, they are not really web services. They are a special form of service made just for Ajax callbacks. This additional file has got me thinking lately about how I can organize the files in my web site so that it doesn’t get too cluttered.
Let me start off by saying that this post is just a diary of my thoughts and I don’t really think I have found the best solution yet. That is why I am putting this out there to see how others are approaching this situation.
Too Many Files
- .asmx – Contains the WebMethods for my ajax callbacks
- .aspx – Contains the layout for my page in typically Asp.Net fasion
- .css – Contains the style definitions for the page layout
So now lets look at a folder on the website which has 3 different pages – a very typical scenario.
This layout quickly becomes unwieldy in its own way. All of the sudden your solution explorer view of your site becomes very hard to navigate and it becomes difficult to maintain the references to all those files. Now if I have a very simple page which has no need for any ajax callbacks or custom css mixed in there, It sort of gets lost in the shuffle
See how your eye can easily miss the ‘MyPage2-Simple.aspx’ page?
A Better Way?
Another idea I had was to have one folder per page which would look like:
This is a little better but it is still cluttered. Just for completeness, lets look at our site with only one js, css, and asmx file.
While this definitely looks a lot cleaner, it also has a code smell of it’s own. Imagine what our common files (js, css, asmx) must look like. They have the code from 3 separate pages all thrown in together.
The last idea I will throw out there is to put each file type in its own folder.
I also like this better than most but it breaks down pretty quickly when you have your web site organized into many folders. Do you keep the script, service, and style files in the root folders or do you have a Script, Services, and Style folder for each sub folder?
Like I said earlier, I haven’t really found a solution that I think is best. Currently, I am trying to organize my project by having each action in its own folder and within these folders I put all the extra files (style, script, or callbacks).
How do you organize your web sites? How do you non Asp.Net people organize yours?
I tend to use a combination of the last example, as well as using just one “main” css and js file. I say “main” because like you said… having everything in one file just doesn’t make sense sometimes. However, I’ve been starting to apply CSS styles to specific tags lately, rather than just creating tons of classes – which makes me put a little more thought into what tags I do use. Do you have at least one “main” css file? I would think that changing basic things like the font color or size for the whole site would be harder than it needed to be if you didn’t.
Anyway, I take the same approach for the JS file. Usually, after a bit of refactoring, I can get my JS functions down to a few that are used a lot. I put those in the main JS file that’s included on every page – then the page specific ones either go inline on the page (if the script is small enough) – or in a separate file which then goes into the “scripts” folder.
Why would you have one css file per page? That seems to really go against what css is about. If your pages share a common design and theme, they should share common stylesheets as well. That way you can update your styles in one place and the entire site updates with it, support themes, etc. I typically break my css up based on its function. something like structure.css, colors.css, tables.css, superCustomWidget.css, etc etc. If I want my entire site to gain a new color scheme, a quick edit of color.css and voila!
Matt – I agree that css has mostly global consistency implications for a web site. On the other hand, if you have to position a specific element on a page and it is only applicable to that page, then it only clutters up the sites main css files IMO. Basically, you have 3 choices:
1. embed the css into the page
2. include it in its own css file
3. include it in the global css files for the site
Like I mentioned in my article, I still have not settled on a way to deal with this issue that I feel is the best way. I have tried keeping all my css in one place and I find that it becomes hard to maintain.
Personally, the first approach to me is the most logical. Keep the site organized the way you would ideally do it, and then “bend” the tool to make it easier for you. if the only complaint is how it looks in Visual Studio, then change how it displays the fiels. You can edit the project file and make Visual Studio treat all of your supporting files (.css, .js. asmx, etc.) appear as sub-nodes to the parent .aspx file. See here for details: http://mikehadlow.blogspot.com/2006/11/nested-files-with-dependentupon-in.html
Why don’t you make your page implement the ICallbackEventHandler interface? That saves you from making a webservice/scriptservice for each page… You know what I mean?
Within each resource folder, I try to group the actual code into files based on common functionality and use filenames that clearly state each files purpose (ie: AjaxManagement.js, Popups.css, ReportingServices.asmx, etc…).
I find that over time, as the web-site grows and evolves, that two or more applications will invaribly end duplicating each other’s functionality. This means that I have to periodically review my design and identify the common aspects that can be refactored and moved to the root level.
| |- g_AjaxFunctions.js
| |- g_ValidationFunctions.js
| |- g_Headers.css
| |- g_Popups.css
| |- g_Grids.css
| |- g_Transactions.asmx
| |- g_Reporting.asmx
| | |- app1_Build_Forms.js
| | |- app1_JSON_Controls.js
| | |- app1_Wizbang.css
| | |- app1_Examples.css
| | |- app1_SlowServices.asmx
| | |- app2_XmlUtilities.js
| | |- app2_Financials.css
| | |- app2_FastServices.asmx