Best Practices for ASP.NET Webforms Project structure - asp.net

When using ASP.NET webforms, I see two main ways to structure a project:
1) Have a lot of .aspx files (including code behind files) and maybe some .ascx files (with code behind files.
2) Rely on a lot of .cs files (class files), and have the classes construct everything with Controls.Add(), etc.
The first method above results in a lot of aspx and ascx files and very few .cs files. The second method above results in a lot of .cs files, but very fewer aspx and ascx files.
Is there a "best practices" way to structure project? Does Microsoft recommend one of these techniques? Is there any information on which of the two styles is used more commonly?

I would stick with the first approach. Some controls are extremely tedious (or difficult) to be created progamatically.
Take the GridView or ListView for example, create an *.aspx page with a GridView which has custom templates with template columns. Then run your application, find the *.dll in the ASP.NET temp directory, decompile the class and look how messy and complicated is the code. It would be very difficult to maintain it over time and/or make changes.
On the other hand, having some declarative code isn't bad as long as you try to maintain the balance.

If you haven't done so, check out ASP.NET MVC. If you cannot opt for MVC you can implement MVP pattern with ASP.NET WebForms. These two patterns provide good way to separate presentation, model and routing.

There is nothing wrong with either approach. Which one you use depends on personal preference, feasibility, and requirements.
One issue you may face is that fewer developers will be able to pick up your project and run with it if you use the second approach, or will take much longer to get up to speed with it. You will find a lot more developers that can easily pick up the first approach and go.

Use approach one as much as possible and only resort to approach two when the out of the box controls do not give you the functionality you require - you can create a custom control by inheriting from an existing control in this case. This is not an "either/or" scenario - you should use both approaches judiciously.

Related

Why are ASP.NET pages (both forms and MVC) dynamically compiled?

There is a pattern in ASP.NET - whenever there is a piece of markup that generates code (like the .aspx/.ascx files in WebForms or .cshtml files in MVC3), these files are dynamically compiled at runtime. aspnet_compiler will produce another assembly for them, which references your code-behind assembly.
This approach seems awkward to me and I don't understand why it hasn't been discontinued already. A much better approach (in my opinion) is like in Winforms or resource files - you have your .whatever file, and then there is .whatever.desginer.cs file. This designer file is created at runtime as you type. When you compile, the compiler doesn't care about your .whatever file, it just takes the .whatever.designer.cs file and produces a single solid assembly.
This provides several benefits:
You can inherit your forms from each other, similar to windows forms;
You can always see the code that is being generated, possibly adjusting your markup to generate better code;
You can easily instantiate strongly typed instances of your forms;
The only benefit I can see from dynamic compilation is that
You can change the markup file anytime and don't need to recompile the app.
To be honest, I've often wanted for one of the first three benefits, but never for the last one. Recompiling the app to see your changes isn't that big of a deal. Especially since you have to do it anyway when working with code-behind, where the most of your time will be. And when you deliver your app to the client, you deliver it as a monolithic, precompiled block. When you update, you update everything, not just individual .aspx files - there's no point to.
So... why is it like this? What am I missing?
It sounds like you are referring to an ASP.Net Website. An ASP.Net Web Application is like an ASP.Net Website, but uses .designer.cs files and produces a single assembly.
See ASP.NET Web Site or ASP.NET Web Application?.
One thought that comes to mind is that the primary difference between winforms and webforms has to do with the common development model.
Namely, there is a whole class of developers and designers who work strictly in html/css/javascript. They use a host of tools ranging from notepad on up to competing development products to build these pages.
Further, in the case of WinForms, MS has complete and total control of what can make up a form. Any controls that can be dropped on it have to descend from their specified code.
However, with HTML they don't have this same level of control. Spec changes occur out of sync with VS releases, additional features are added that are browser specific, etc. In short, they can't guarantee that a particular element in the HTML file is a valid element at all. All they can hope for is that whatever is sent was done so on purpose and that the browser knows how to deal with it.
Now they have tried to implement a model that provides visual inheritance. It's called "master pages". However, I believe the only tools that properly work with master pages are VS and Expression. Getting the other vendors to go down this path would be nearly impossible. Also, they've added the concept of "nested master pages" such that you can get multiple levels of inheritance out of them.
The code behind model helps to implement non-visual inheritance allowing people to completely revamp page processing (hence how MVCx works).
Which leaves us with the parts that MS does know about. Obviously they do have a .designer file which backs the .aspx pages. This designer file maintains the server control list that is accessible by the code behind. You could add runat="server" to every regular element in an html page (excluding artifacts like css) but this would increase the amount of processing required for the page.
To sum up, I think they've picked the best model they could for web development given the lack of control they have over how the web works. Other vendors have tried similar paths (e.g. Adobe Contribute, previously by Macromedia). I believe some of those even predate MS's model.

Do you store your helper classes in a separate assembly?

I just want to know if anyone stores their helper classes or methods in a separate assembly and why...just for clean management of them? I've seen so many posts about using a helper folder inside your MVC project and that brings me back to the messy old days in ASP.NET where people were using an App_code folder instead of cleanly separating things out physically like this into its own project.
And likewise nobody doing real architecture is going to put models in some folder in your MVC web assembly. They would go in MyApp.DataLayer assembly or MyApp.Models or something like this.
Yes, but for reasons, which are common to other assemblies as well
Becomes easy to plug into any other project.(might need some editions).
Reusable
Easy to improve
Easy to refractor
As not part of a project, but project
itself, it is easy to document and easy for developers to understand
Clears out some of the mess
But for all that above, your assembly, when ready, should be a "job well done", other wise, it is better to keep the helper classes to where they belong.
We have some helpers in a separate project and some in the web project. I think you'll find that some of your helpers need to use abstractions that you've defined in your web project itself. And that will often force you to put those helpers into the web project, because it's not likely desirable to have some other project that has a reference to the web project. I don't consider it the same as using App_Code. These are files that are compiled at compile time inside your IDE, with no special "magic" that gets applied to App_Code.
I use projects to separate out the different layers in my web or form apps. It allows me to respect the business rules better. Also I find it easier to track down where I need to go if I want to make a change.
But I have seen people use folders that label the layers in the solution but I think that is a little messy.
Yes, because they are part of the Business Layer. Two big payoffs:
Reusability
Testability
Keep in mind that your utility functions and helper classes are likely to be some of the most heavily used components of your entire system. Without full BICEP testing, you run a truly unacceptable risk.
Most helpers that I create are usually layer specific so I tend to keep them with the assembly the base assembly that needs them. I don't see a reason to add in another project to store a large number of specific helper classes.

Asp.Net inline (single-file) vs code-behind

In the transition from classic ASP to Asp.Net some developers took to putting their server side code in a block at the top of their HTML ala:
<%# Import Namespace="MyDll" %>
<script runat="server">
void Page_Load()
{
}
</script>
This single-page model has some advantages as Jeff Atwood describes, however, in my experience I have seen nearly all code put in a separate code-behind file in recent times (ie with VS 2008).
Nevertheless, it turns out a colleague strongly prefers the single file (inline) method over the separate code-behind method.
What are the strengths and weaknesses of each approach? (I've noticed that code collapsing and #regions don't seem to be supported. Also the pages get rather long and there is no longer the visual separation of client and server side code. Can you tell I have a preference?)
I realize that variations of this question have been asked before, but I haven't seen anyone actually spell out specifically the pros and cons of each method.
EDIT
Thank you everyone for your thought provoking answers. I'm still hoping for a list of strengths and weaknesses of each method. What are the actual features that each has (or doesn't have)?
There's no doubt in my mind that the code-behind or mvc models are superior for almost everything you want to do. However, even today I still find myself using inline code for most of my pages. Why? Because there's one big scenario where the inline scripts really shine.
If you have a large amount of legacy ASP Classic code that you don't want to just throw out, including a deep nesting structure, it all lives in one big application, and you want to share that application with your asp.net code, you can just drop inline asp.net pages right in your existing web file system and they'll just work.
This sounds like exactly where your other developer is coming from.
Because codebehind is just a class it has all of the advantages like inhertance and interfaces. It also enhances readability.
Single page has mostly been replaced by mvc for applications that focus on outputting data instead of implementing businesslogic.
Have you considered looking at ASP.NET MVC instead? It will allow you to overcome this dilemna in a very clean seperation.
Generally, when working in WebForms, the trend I've seen is to use a code-behind. Many* WebForms applications that I've seen in the field have too much in their code-behinds, and the separation is almost critical just to be able to understand all the logic.
However, in a well-designed app where the UI is only doing a UI job, and passing all the logic and heavy lifting to a different app layer, a single-file solution will often end up being more elegant and easy enough to traverse. In a way, going with the single-file solution may -- in the right hands -- motivate a better separation of concerns, because you don't want that one file (which provides your UI) to get cluttered with a bunch of business logic.
In the ASP.NET MVC model, the default is single-file. This is, again, to stress separation of concerns and good application design. (I do not know off the top of my head if the ASP.NET MVC kit provides a code-behind concept. I have not used it if it does.)
Ultimately, YMMV. Good developers tend to write good code whether it uses the code-behind or single-file model. Bad developers tend to write bad code either way, too.
* Obviously not ALL!
Inline code is procedural in nature and lacks separation of concerns...
One of the selling points of ASP.Net was the the code-behind and the server controls. It was thought to be bad to have inline code. This changed when ASP.NET Mvc came on the scene -- inline code became "hip" again.
If I had a choice and all things being equal using the code-behind is a better approach. I strive to keep as much logic/code out of the UI.
Even using the code-behind, while it is a class, it can become a tangled mess. I found that using MVP or some variant of MVC with web forms made development more maintainable in the long run.

ASP.NET project organization

This may be a broad question because part of the problem is that I actually don’t know what the question is. What I would like to know is how you commonly organise ASP.NET applications in terms of placement of pages (aspx), user controls (ascx), server controls and other support classes and utility functions etc. First, let’s assume that there is already some data layer somewhere (perhaps in a different project). This is the not issue.
The issue I frequently face is that create several pages and realize that they need to share some common rendering logic or some utility function, class etc. Another typical case is that some pages become too large so that it seems handy to split them (say into some user controls). What is the best place to put these utility classes, share classes, user controls, server control etc.? Here are several possibilities.
Don’t really care about any organisation and place all types of files next to each other. So in one directory, you may have an aspx files, some cs files etc. This is not really an option probably.
Organize files by types. Let’s say you create a directory for user controls and put all user controls there. OK, but what about server controls and other regular classes? Should they be in special directories as well? It does not sound right. What I dislike most on this is that when you work on a feature (logically related piece of code), you must hunt it all over the place. I think that features and logical sections of your applications should be also grouped on the file system level in some way.
What I would like to have is to have the pages (aspx), user controls (ascx) and handlers (ashx) basically as dummy placeholders sitting in the directory structure organized from the logically according to the point of view of the outside visitor while the actual code (page, user controls implementations, serve control and utility classes) should be placed in s different folder structured into logical namespaces (organized by the modules or features of the application). It seems to me that the only way to achieve this is to manipulate the <%# Page ... %> directive manually.
Does it sound crazy? Am I asking too much? Is there a better way? What are your best practices? Do you know some good examples?
Edit: Another idea. This does not mess up with the generated aspx, aspx.cs and aspx.designer.cs files. One on my original requirements was that I wanted to place the code driving aspx pages to my own location and put it to a custom namespace hierarchy. So what if I simply subclass the aspx classes generated by VS? Let’s say I have a project called MyApp and MyPage.aspx page in it. VS then creates MyApp.MyPage inherited from System.Web.UI.Page. I leave this class be (no code will go there), but create a subclass, say in MyApp.SomeNamespace.SomeSubNamespace.MyPage, inherited from MyApp.MyPage. This way MyApp.SomeNamespace.SomeSubNamespace.MyPage will get access to the autogenerated protected fields corresponding to the server controls of MyApp.MyPage and I’ll get an entire "private" namespace for all the support classes which are related to this page. Any major disadvantages? Another related problem which bothers me is where should this new cs file be physically placed? In web projects, there is a standard folder for it called App_Code, but I’m interested in web applications. Creating a directory in the root of the application (such as Code) does not sound right.
Remember that you can create page classes that don't actually correspond to any markup. We often create base pages that our actual UI pages inherit from. This is a simple way of organizing "base" page functionality. Then when you create your .aspx pages, make them inherit from the base page class, rather than System.Web.UI.Page.
We usually place our base page .cs files into the top level directory if it's a small project, or for slightly larger projects we'll create a "Shared" or similar directory where they live.
However, we also have a huge enterprise web project, and we simply build our webcontrols and base pages into a class library called CompanyName.Web.UI, with a couple sub-namespaces to that. All our actual web site projects import that assembly and all the code for the controls, etc. is elsewhere. This sounds like it might be a good option for you.
If you remember that your .aspx codebehinds can inherit from any class file, it should make it easier for you to organize.

Web Parts with a markup file?

I'm an ASP.NET web part novice. I've built a few simple ones using only a class that derived from WebPart and overriding the CreateChildControls method, but nothing really very substantial. My question is whether it's possible to have a web part that also takes advantage of a separate html/asp.net markup file that will help provide some structure to the web part's output. In the past I just created server controls and added them to the controls collection, but this seems like a silly way to try to create a non-trivial layout. Can I do this? Do I have to use an ascx user control or can I bypass that step? There are a lot of hello world tutorials on web parts out there, but none seem to go past the CreateChildControls override. Thanks!
Yes, there is. Go here to learn about templated web parts, and go here to see all of the info he has on WebParts. I used this technique back in 2004/2005 and it worked very well.
The links in the above answer are no longer working, but here is an alternative one:
http://www.a2zdotnet.com/View.aspx?Id=95
In VS 2010 we also have visual web parts, that I think do pretty much the same trick but it's wrapped in a project item. I've only seen this in the context of SharePoint so not sure how it works for ASP.NET projects. Here is an example:
http://msdn.microsoft.com/en-us/library/ff597539.aspx

Resources