April 30, 2006
Custom email control
For whatever reason, creating custom ASP.NET controls is something that is ... uh ... underrepresented in my skill set. As with certain other corners of the product, my theoretical knowledge outstrips my practical knowledge. So when I was messing around with a couple of things recently, I thought that they might be good practice scenarios for creating some custom controls.
The thing about custom controls is that the concept is really quite easy to grasp. You inherit from, say, WebControl and you override Render, and you're in business. And if you're working in VS2005, the thing practically writes itself. (haha) The base control class does an amazing amount of heavy lifting and -- again, in outline -- you only need to add your control-specific logic.
As happens, though, the difficulties lie in the details. I have found that to be true even with the very simple controls I've done -- there's always a gotcha or three that makes (at least for the less-experienced, like me) for a certain two-steps back type of development. Which I guess is where all the fun is.
I thought about listing the source here, but it's slightly too long, so I put it into an .htm page. These are the points to call out, I guess.
When the user clicks the control, it does whatever mailto: does on their machine.
The control exposes these properties:
- EmailLinkText -- what the user sees. If no value is specified, the control constructs the link text out of the target email name and displays it as
EmailName AT Domain DOT Extension. (The strings
" AT " and
" DOT " are configurable.) Note that the user doesn't have to translate this back into an email address, coz the link is clickable.
- FullEmailAddress -- the email address for that link. Data-bindable, thanks to the Power of Attributes. You can specify the recipient using a complete email address, or you can specify ...
- EmailName, Domain, and Extension separately. (Also bindable.) Your choice.
- DomainDelimiterText and ExtensionDelimiterText. In case the strings
" AT " and
" DOT " are not to your liking.
I had initially tried to implement a feature that ended up costing me about 90% of the time I spent screwing around with this. I had thought that I could (should) make the FullEmailAddress and EmailName/Domain/Extension properties reciprocal -- setting one would populate the other(s). Boy, as far as I can tell, there's no clean way to do this within the control itself. For starters, you don't want to overwrite any values that the user sets, so you don't want to just barge in there and set the properties willy-nilly. Instead, I had a notion that if and only if FullEmailAddress was not set, it would return the combination of EmailName/Domain/Extension (and vice versa), without necessarily setting those properties explicitly. This is codable inasmuch as you can look for
If ViewState("FullEmailAddress") Is Nothing, but the problem is that it doesn't stay
Nothing for long. In my test page, once the text boxes had been populated with one of these based-on-the-other property values, it was as if the user had entered those property values, and on postback, ASP.NET happily set those properties, so they were no longer null. (Make sense?) In the end, I gave up on the idea of reciprocal properties, although there might be a way to do these. As a compromise, and because this seemed like it might be useful in some circumstances, I implemented the read-only properties FullEmailAddressEmailName, FullEmailAddressDomain, and FullEmailAddressExtension, which return the parsed components of FullEmailAddress.
There is one 2.0-specific feature in this code. The RegisterClientScriptBlock call, which is exposed via the ClientScript page property, has a new 2.0-specific overload. But you can use uncomment the corresponding 1.1 version and it seems to work fine -- I tested it on Web Matrix, yahoo!
So that's the first control. Another one another time.