DaedTech

Stories about Software

By

The Fragile Genius of Webforms

Turning Desktop Developers into Web Developers

I’ve been doing a lot of Webforms (ASP.NET) development over the last four months, as I’ve mentioned in some posts. Before that, I was doing a lot of WPF development for desktop applications and before that a hodgepodge of things that included web development with the Java stack. I had done very little with Webforms (though I had dabbled with a couple of internal corporate applications), so wrapping my head around it has been interesting.

For those of you not familiar with the way Webforms works, it could probably best be summarized as “helping you write web applications without realizing that’s what you’re doing.” Okay, that might be a bit snarky, so let’s go with “making windows desktop developers comfortable with writing web applications.” (in particular Winforms developers). It goes out of its way to create an abstraction layer that represents web concepts as their desktop equivalents which, I believe was done with the intention of easing the transition of a generation of Winforms developers to web application development. And, well done. I think it was wildly successful at that.

Indeed, it’s quite possible to write code for Webforms apps without understanding anything about HTTP, statelessness and the client-server nature of the web and understanding next to nothing about Javascript, HTML, and CSS. Instead of these concepts, Webforms developers are deal with concepts like “button click event” and “user control” ala Windows desktop development. It’s really quite a concept — “keep doing what you’re used to doing, and we’ll handle transforming the result from desktop apps to web apps.” It took me a while to stop wondering when I’d stop writing everything with wizards and datasources and gridviews and start outputting some templated markup with binding logic. It happened in trickles and drizzles but never really at all beyond that.

If your web experience is in any other technology, you’re certainly used to a less monolithic approach. Rather than “controls” that generate reams and gobs of HTML/CSS/Javascript behind the scenes, you’re no doubt used to the template approach where what you’re looking at is more or less HTML but with some notation for binding to a model and handling core concepts like iteration, validation or missing data. Perhaps there is also some notion of inline script execution. This is definitely how life works with technologies like JSP, PHP and even ASP.NET MVC. Developers using those technologies understand and embrace web as a delivery mechanism and architectural component and divide work up accordingly.

But not with Webforms. Webforms evens the playing field using wizards, WYSIWYG and extremely involved abstractions to make everyone working on a Webforms project a Webforms developer. Webforms actually abstracts understanding of underlying concepts away from the developers in this fashion, the way that Front Page and other such code generation tools have in the past. Karl Seguin gives an excellent Webforms vs ASP MVC summary that touches on these points and others.

A Brief Foray Into Architectural Philosophy

Persistence technologies, messaging/communication with externalities, web vs desktop are all non-core implementation details. Oh, don’t get me wrong, they’re important. But ebay doesn’t have an Oracle DB application or even a web application — it has a consumer resale application. The core of their business is enabling resale and that transcends the current technology stack. If Oracle went out of business tomorrow and a unified web became passe, ebay would no doubt try to soldier on by switching to MySQL and peer to peer app communication (or whatever). If people stopped wanting to resell goods, on the other hand, ebay would be kaput.

To staff a project that scales beyond tiny (i.e. multiple developers and up) a sensible way to divide up the work is to have some core business rules programmers and then others specializing in various satellite aspects of the application. So ebay might have people that develop server side application/business logic, people that specialize in Oracle stored procedures and people that specialize in web as a delivery mechanism and it would be expected that those people be domain experts, database experts and web experts, respectively. (Not to say that there couldn’t be some fluidity among these groups according to skill-set or availability and learning curve).

This separation of skills required in a team environment allows for the pairing of team members with tasks for which they are best suited. These pairings, in turn will naturally tend to foster productive collaboration, division of labor and generally good morale. People, especially knowledge workers like software developers, prefer autonomy and that tends to exist in greater abundance when each team member has a unique skill set that he or she is applying. A project with an architecture like the one I’m describing is more likely to be staffed by happy and productive developers.

Webforms and Generalist Mediocrity

Webforms does not lend itself well to the sort of architecture that I’ve just described. It invites developers to use controls that completely automate and obfuscate the generation of client side markup and scripts. But beyond that, it invites developers to describe the persistence layer in the specialized markup as well (the various “data sources” and their wizards), in effect flattening the application and rendering it monolithic. As such, Webforms developers can be (can be — not must be, please don’t misunderstand my point) relatively low-knowledge generalists whose only specialty is, well, Webforms. Webforms itself is the one with knowledge of different application layers and architectural patterns.

Image by “Scottius11” via wikimedia commons.

Whoah. Let’s think about that for a minute because it’s actually fairly profound. In a Webforms project, it is Webforms itself (or, more accurately, the people who designed ASP.NET) that understands the technologies involved. Webforms is your most knowledgeable ‘stakeholder’. Most successful frameworks and architectural technologies offer a cafeteria plan of sorts to let developers pick and choose what they need and want and to allow people to be paired up with particular facets of an application (a lot of IoC containers and various toolkits have this property). They empower developers. Webforms instead offers them a crutch — a way to perpetually develop applications without really understanding how they work.

Imagine that you owned dogs all your life but decide you want a cat. Now imagine a team of engineers coming along to ease the transition. They build a wooden “Trojan Dog” with a litter box in it so that you can “walk the cat” to get it to go to the bathroom. They build a sound altering muzzle so that when the cat meows, it sounds like a bark. They give you toys and pants loaded with catnip so the cat will ‘retrieve’ the toy and bring it back to you in game of ‘fetch’. In short, they create all manner of pretty elaborate and impressive adapter tricks to allow you to own cats and pretend that they’re dogs. They probably also do a bit of hand-waving when asked why this scheme makes any sense.

The Genius And Fatal Flaw

Like the hypothetical “dog to cat transition technology”, the Webforms abstraction of all things web is impressive. It’s impressive for a group of developers to be able to create a technology that allows tens of thousands of people to write applications without really understanding the underlying technology stack (again, not in all cases — just saying it’s possible). It’s impressive for those developers to create something that allows other developers to generate a radically different type of application without having to learn much in the way of new skills. I can’t overstate that — it’s amazing.

But the same thing that makes it amazingly effective at bringing old school Winforms developers into the 21st century also limits their growth and that of the applications that they produce. Webforms is a “helicopter parent” that doesn’t, on its own, know how to stop telling its 17 year old child when it’s time to brush his teeth and wash his face, and thus it runs the risk of perpetuating learned helplessness in the same. The internet is no longer new and alien, and our web development toolbox should reflect that.

ASP.NET MVC is slick, powerful and impressive as a framework. Developers should be comfortable with Javascript, HTML and CSS if they work on the client side. Developers should be familiar with IoC, communications protocols, decoupling and testing if they work on the server side. They should be using frameworks to enhance their knowledge and speed their work and not to handle everything for them so they don’t have to understand. It’s time to appreciate the genius of Webforms, acknowledge its importance, and wish it well in retirement.

By

ASP Webforms Validation 101

Today I’m going to delve into a topic I don’t know a ton about in the hopes that someone who knows less than me will stumble onto it and find it helpful. As I’ve alluded to here and there, I’ve spent the last couple of months doing ASP Webforms development, which is something I’d never done before. I’ve picked up a handful of tips and tricks along the way. Today I’m going to walk through the basics of validation.

Start out by creating a new ASP.NET Webforms project:

This gives you an incredibly simple Webforms project that we can use for example purposes. If you open up the login form, you’ll find a boilerplate login form laid out in markup. Let’s take a look at the User Name controls:

  • User name
  • What we’ve got here is the most basic form control validator, the required field validator. The “ControlToValidate” attribute tells us that it’s going to validate the “UserName” text box and the “ErrorMessage” attribute contains what will be displayed if the validation fails (i.e. there is nothing in the field when you submit the form):

    Pretty standard stuff. Let’s switch things up a little, though. Let’s add another label after the text box with something goofy like “is logging in.” This is something I bumped into early on as a layout issue and had to poke and google around for. Here’s the new look for the markup:

  • User name is logging in.
  • And here’s what it looks like:

    But that’s no good. We want this on the same line as the text box itself or it looks even goofier. Well, counterintuitive as it seemed to me, the validator field defaults to taking up the space that it would occupy if it were always visible. You can alter this behavior, however, by adding the attribute Display=”Dynamic” to the validator tag. Once you do this, the new label will appear on the same line–unless you mess up. Then the validator will resume taking up space, bumping the new label to the next line. Okay, okay, I’m no UX guru, but the important thing here is that you can set the space occupation behavior of your validators.

    The next lesson I learned was that I could use validators for comparing values as well as doing typechecks. This tripped me up a bit too because I would have assumed that there was some kind of TypeCheckValidator, but this isn’t the case. Instead, you have to use CompareValidator. Let’s say that we want users to have to log in with a decimal representing a valid currency. (“Why,” you ask? Well, because we’re insane 🙂 .) This is what it would look like:

  • User name is logging in.
  • The new validator shares some commonality with the existing one, but take special note of the “Operator” and “Type” attributes. Both of these fields are necessary. For anyone who has read my various rants about abstractions, would you care to guess why I found this completely unintuitive? Well, I don’t know about you, but I personally don’t tend to think of “DataTypeCheck” as an “Operator” (perhaps an “operation,” but even that seems like a stretch). I would have expected either a DataType validator or else the Compare validator simply to need the type specified, at which time it would do a type check. But, I digress.

    The next sticking point that I encountered was that I had a particular form where I wanted to validate something that wasn’t part of a text box. I thought I was dead in the water and would have to do something sort of kludgy, but CustomValidator was exactly what I needed. Let’s say that I wanted to verify that the weird label I’d created does not, in fact, contain the word “is.” (This isn’t necessarily as silly as it sounds if there’s code that alters this label dynamically based on other inputs.) If I point any validator at this control as the “ControlToValidate”, I’ll get an exception saying that it cannot be validated. But I can omit that property and specify an event handler.

    Add the custom validator to your markup and you get this:

  • User name is logging in.
  • And add the following to your code behind:

    public void PointlessLabelValidator_ServerValidate(object sender, ServerValidateEventArgs e)
    {
        var labelText =((Label)LoginControl.FindControl("PointlessVerb")).Text;
        e.IsValid = !labelText.Contains("is");
    }
    

    Now launch the web app again and type a number for the user name and something for the password and observe the new error message. It’s important to note here that you need to satisfy the other validation constraints because the custom validator operates a little differently. The validators we’ve added up until now work their magic by sending validation java script over the wire to the client and so validation is client-side and immediate. Here, we’re performing a server-side validation. This server-side custom validation will be short-circuited by client-side failures, which is why you need to fix those before seeing the new one.

    And that’s my brief primer on validators. This is neither exhaustive nor the equivalent of a nice book written by a Webforms guru, but hopefully if you’re here it’s helped you figure out a few basics of Webforms validation.