Today the perception is the average ASP.NET developer works with ASP.NET MVC and only losers still use WebForms. Well think again. Despite MVC's popularity, especially with folks like myself that seem to be consumed with web technology, WebForms is still the engine that drives the majority of ASP.NET applications. It is a very mature platform with millions of applications world-wide.
Various telemetry sources I have been exposed to over the past year indicate roughly three out of four ASP.NET developers use WebForms as their primary web platform. Yeah it’s hard to digest, but why do you think component companies like DevExpress, Telerik et al are still producing WebForms products? It’s popular.
But despite its popularity and maturity, there are many bad practices that still seem to propagate and need to be stopped. Let's examine 5 practices ASP.NET WebForms developers should avoid.
1. Control Style Properties Instead of CSS
Back in 2001, when ASP.NET was first introduced it was architected as a natural way for desktop developers to create web applications with a small learning curve. It was designed to replicate the developer experience they had become accustomed to building desktop applications, typically in Visual Basic. In Visual Basic (let's say VB 6 for the sake of reference) a developer would drag a control on a view's design surface. They would then proceed to set various properties in a properties window. Things like dimensions, colors, fonts, etc. This practice was carried over to ASP.NET. Despite making it more natural for developers it produced less than optimal markup. Each control property defined by the developer would be written to the DOM as an inline style. As we have come to learn this is detrimental to performance and maintenance.
The preferred practice for styles is to include all style references in external files so they can be browser cached. The CSS file reference should also be placed in the document's HEAD. This means all styles will be loaded when the page is loaded and not as the DOM is parsed.
Another problem caused by inline styles is overly replicated style rules. Think about it, if I have a form with 10 input fields using properties to define the dimensions and font styling each one will have the exact same inline styles defined. This adds more and more weight to the overall page request, which slows down the user experience. The user experience is poor and the long term maintenance is now more complicated.
Using CSS rules defined in a style sheet means there is a single point a developer would need to focus for future updates. It also means the CSS rules will be cached by the browser on subsequent requests, again reducing load time.
Another advantage ASP.NET WebForms developers gain is intimate knowledge of CSS and how browsers apply rules. As I finished my last book, on ASP.NET WebForms, I was watching the world around me evolve with jQuery and more and more pure CSS layouts. As a WebForms developer I felt lost. I decided I needed to retool my thought processes to relearn how HTML and CSS worked. I am glad I did because now I am much more comfortable creating modern web applications. Relying on the ASP.NET Web Control properties and abstractions actually caused me to become a lower quality developer in the end. And it is important to have a fundamental understanding of the technologies you use on a daily basis.
So avoid using the ASP.NET control's property pages to set values that should be set in CSS.
2. Use Feature Detection, Not Browser Detection
Nothing is more frustrating than loading a page in Internet Explorer and only seeing a blank white page. We have all done it even if you wont admit it. Many line of business applications are just the opposite and will not work outside of Internet Explorer, especially obsolete versions. This is crippling as a consumer focused web site or a line of business application.
Typically what happens in these situations is the application detecting the browser type either on the server or in the client. Browser type refers to either Internet Explorer, FireFox, Chrome, Safari, etc. This is a really bad practice because you are assuming a broad knowledge of thousands of browsers. By doing this you incorrectly limit your potential audience.
Modern browsers like Internet Explorer 10, Chrome and FireFox offer many, consistent features and interfaces. Sure there are a few APIs supported by Chrome that are not supported elsewhere and visa versa. But by in large the different browsers are a consistent pallet for designers and developers to confidently build rich client experiences.
Despite making assumptions about what features or functionality the browser supports the browser caps file is usually not up to date. This means using it is not reliable even to determine the browser. Why is it out of date? Well new browsers are released almost daily now. Android is one of the reasons as there is a new Android phone released every hour (tongue in cheek). There are thousands and thousands of browser variations these days. The browser caps file is maintained and distributed by Microsoft. While they do a pretty good job they cannot push updates to every machine every day or even every month. The file is only updated every few months at best and even then it is not really complete.
Instead of performing server-side browser detection switch to client-side feature detection. Typically using a library like Modernizr is the best option. It makes it easy to detect browser supported features with an easy way to dynamically load browser polyfils as needed. This can patch much of the functionality needed for your application to run naturally even on the oldest browser platforms.
3. Never Set EnableViewStateMac To False
When EnableViewStateMac is set to true, the default value, the view state is encrypted on the client. This should always be the setting, even when not using view state. When this property is disabled the page's security cannot be ensured. When set to false it opens the page up to potential tampering. So, do not change this property.
4. Long Running Requests
Sometimes slow queries or data requests just cannot be avoided. Making the user wait while the server waits on this data to become available creates a very bad user experience and can cause overall issues with browser performance.
If a request is being processed on the server and makes a query to the database that takes several minutes to fulfill, it is locking the request and may even timeout. This leaves the visitor waiting for something to happen, and trust me end users are very impatient. This is bad for another reason: the server's CPU is also waiting cycles waiting on the request to complete. This means the overall server utilization is dropped, meaning you will need more hardware or virtual machines to handle the load. The user is frustrated and your operations overhead is increased.
If you cannot avoid these long operations you should migrate those requests to either an AJAX call or consider using something like SignalR to leverage WebSockets. This returns the request to the client, freeing the server to process other requests and the client can allow the user to continue shopping or working. When the request is processed the client can be notified to process the request.
5. Avoid Page and Control Callbacks
Another AJAX topic is page and control callbacks. These were originally created as end points when AJAX was just becoming popular. They were early attempts at defining a server-side end point for these AJAX calls to hit. Today you know it is a better idea to define a real API with ASP.NET Web API, WCF, MVC controller or even an HttpHandler. The ASP.NET WebForms page and controller callbacks are an extremely inefficient method to accomplish AJAX end points compared to these alternatives.
ASP.NET WebForms remains a very popular platform to build web applications. Just like any other tool or platform there are some best practices that should be followed. In the case of WebForms it is a very mature framework with some legacy features that when introduced seemed like a good idea but have not panned out over time. Because these features remain in the framework for backward compatibility there is a natural temptation to implement them. These are just a few tactics and practices that should be avoided if possible. If you are in doubt about a feature you should do some research to determine if there is a better way to implement, especially when it comes to security and performance.