October 2003 - Posts

The Hardest Part of Writing a Book
30 October 03 08:42 PM | Scott Mitchell

For me, the hardest part of writing a book is... getting started. The first chapter always seems infinitely more difficult to write and takes far more time than any of the remainding chapters. And, for that first chapter, the first paragraph of that first chapter can sometimes take hours. Hours! My initial attempts never fail to go something like this:

  1. Open Word,
  2. Write the title of the chapter at the top,
  3. Start to write the first sentence of the first paragraph of the chapter.
  4. Write a few sentences.
  5. Delete sentences written in step (4).
  6. Return to step (3).

This process is usually repeated until I get too frustrated and play Solitaire or, if I'm really frustrated, trek downstairs to play some Return to Castle Wolfenstein on XBOX Live (that never fails to pick up the ol' spirits).

This process is usually made even more frustrating because I already have, in the noggin', decided how I want some part of this chapter to look, but I really want to start from the beginning. Eventually, I capitulate and decide to just start writing a sentence in the middle of some paragraph somewhere in the middle of the chapter. And then it flows from there, usually. It takes a few days, sometimes a couple of weeks, before I'm back into the writing flow, churning out 10-20 on days I write, but prior to “getting in the zone” I am happy to put out one or two pages in a day's time. Meh.

(If you couldn't guess, I recently, as of this week, started working on another book.... Details to follow once I get back in the zone.....)

Filed under:
A Blog Feed ASP.NET Server Control
24 October 03 04:14 PM | Scott Mitchell

Decided it would be cool to create a blog feed ASP.NET server control, so I did. It's not yet 100% complete, still want to add a few miscellaneous features and true VS.NET Designer support, but that will come this weekend likely. The control caches the RSS feeds in the data cache for a developer-specified period (defaults to 60 minutes) - do you think it would be worthwhile to add support to cache to disk as well?

Anywho, you can see a very simply version of the control in action here. Note that the complete code needed to get this output is just:

<%@ Register TagPrefix="skm" Namespace="skmRss" Assembly="skmRss" %>
<SCRIPT language=C# runat="server">
  private void Page_Load(object sender, System.EventArgs e)
  {
   if (!Page.IsPostBack)
   {
    sowFeed.DataSource = "http://scottonwriting.net/sowblog/Rss.aspx";
    sowFeed.DataBind();
   }
  }
</SCRIPT>

<skm:rssfeed id=sowFeed HeaderText="ScottOnWriting.NET" runat="server">
</skm:rssfeed>

A somewhat prettier version of the control in action can be seen here. The source code is the same as above, but the control's declarative syntax requires a bit more work (although through VS.NET the “work” is merely flipping a few properties in the Design tab...):

<skm:rssfeed id=sowFeed HeaderText="ScottOnWriting.NET" CellPadding="4" 
         Font-Size="10pt" Font-Names="Verdana" runat="server" 
         HorizontalAlign="center" width="80%">
    <ALTERNATINGITEMSTYLE BackColor="#E0E0E0" />
    <HEADERSTYLE Font-Size="14pt" BackColor="#000040" ForeColor="White" Font-Bold="True" />
</skm:rssfeed>

I will be adding this project to the GotDotNet Workspaces sometime this weekend, if you're interested in getting access to the control and/or code.

The Question Every Author Should Ask Themselves
24 October 03 12:54 PM | Scott Mitchell

Have you ever noticed how most technical authors can be divided into one of two camps: either they write books geared for beginner/intermediate developers, or they write for the upper-tier of developers. Take, for example, someone like Don Box. Don has written a plethora of books on COM and the underpinnings of .NET, books clearly aimed at advanced developers. I have a hard time imaging Don would write a book titled, Write Your First Visual Basic .NET WinForms Application!, and for good reason. On the opposite end of the spectrum, consider Wallace Wang's impressive list of For Dummies books. Here is a prolific author who has written dozens of books for beginners.

It seems to me that when choosing a career in technical writing I think it is important for the author to ask himself an important question early on: “Do I want to be an expert for an advanced topic, or do I want to write 'howto' books for beginners?” Choosing a particular direction can lead to better noteriaty among the group you are writing for. When you say, “I'm reading a book by Don Box,” people know that you are an expert in your field. So, what would you rather do? Write for experts or write for beginners? There are advantages and disadvantages to both.

If you are writing to become known as an expert in a particular field, then clearly it would be more beneficial to write for an advanced audience. Authors who use books as a means to publicize their skills for consulting jobs or resume fodder would do best, in my opinion, to pick a specific topic they enjoy, become an expert, and write highly targetted books on said subject. The downside to writing for advanced developers is that, sadly, there aren't very many of them. This, of course, means fewer sales. Writers that rely on techincal writing as their main source of income would, I imagine, do better by writing for a larger beginner-level audience.

There's also the enjoyment factor of it all. Do you like explaining technologies to people who are just starting out learning about said technologies? Or do you view that process as tedious hand-holding? Is it important that your peers view you as an expert on an particular topic, or could you care less if you're known as “that guy who explains things to newbies?” Personally, I prefer teaching beginners. There's nothing as rewarding as seeing someone new to a technology, and being able to help them explore the new territory. Seeing the lightbulb come on when someone picking up the technology “gets it,” is sometimes payment enough. (Sadly the bank doesn't view this good karma as legal tender.)

Regardless of what path you choose, I think it best to pick a path early on in your writing career. Not being one to follow my own advice, I have written books ranging from the beginner-level (Teach Yourself YYY in XXX) to books geared toward an intermediate to advanced crowd (Designing Active Server Pages, ASP.NET: Tips Tutorials, and Code, and ASP.NET Data Web Controls). I am about to embark on my sixth book, and this book will be heavily geared toward the beginner crowd, even moreso than the Teach Yourself YYY in XXX books, hence my ruminations on this topic...........

Filed under:
Data Access Application Block Talk Tonight
21 October 03 10:18 AM | Scott Mitchell

For those readers in the greater San Diego area, I'll be giving a talk tonight on using Microsoft's Data Access Application Block (DAAB) for the San Diego ASP.NET SIG. The cost is free, the talk will be a bit over an hour I anticipate, and will, hopefully, be informative and useful for all. You can learn more about the meeting time and location here.

If you cannot make it, don't fret, the presentation is available here. Also, for more information consider reading John Jakovich's Examining the Data Access Application Block article.

Hope to see you this evening!

Filed under:
Challenge: Emailing the Contents of a DataGrid with a ButtonColumn
20 October 03 10:06 AM | Scott Mitchell

In an earlier article on 4Guys, Emailing the Rendered Output of an ASP.NET Web Control, I looked at how one could, with just a bit of code, have the contents of a Web control emailed in an HTML-formatted email to a specified recipient. Below is a screenshot of a DataGrid emailed to myself using the code I discussed in the previous article. Practical uses for emailing the rendered contents of a data Web control might be to send a user's shopping cart, or send an online invoice, or any other number of features where the data is presented in a data Web control and the user wants some form of an email receipt.

Since the article's inception, I have received a few emails from alert 4Guys readers saying that if the DataGrid has a ButtonColumn (or an EditCommandColumn, or a TemplateColumn with LinkButtons or Buttons), that attempting to render the DataGrid results in an error. This occurs because when the DataGrid's control hierarchy contains a Button or LinkButton, when this Button or LinkButton is rendered, the Page.VerifyRenderingInServerForm() method is called. This method checks to ensure that rendering of a server form has started before the control is rendered.

Now, the challenge I propose to you, the six people who read my blog, is: “How can this be overcome so that an email can be sent?” I have already thought of a couple of ways, and ASP.NET server control God Andy Smith has also provided some suggestions... but I'm interested to see what ideas others can come up with. Both mine and Andy's ways feel like hacks. I'll be happy to share them soon enough (in the form of an upcoming 4Guys article nonetheless), but am interested in alternative approaches. (Rather than take the time to share Andy's approach and my approaches, I'd rather just let those who care to respond to free-think on their own...)

Filed under:
Setting the DataList's SelectedIndex Programmatically
17 October 03 11:09 AM | Scott Mitchell

Have you ever tried to set the SelectedIndex property of a DataList programmatically, so that the SelectedItemTemplate will be used? For example, you might be binding to the DataList information about products, and you might want to have the cheapest or most expensive product “selected” so that it is rendered via the SelectedItemTemplate. Initially, you might think to solve this problem by creating an event handler for the DataList's ItemDataBound event, and then to programmatically set the SelectedIndex property based on the index of the row that meets whatever criteria you have outlined to be “selected.”

Sadly, this approach won't work due to the order of events in rendering a DataList. Let's step through the series of events that transpire when the DataList's DataBind() method is called. For each item in the DataList's DataSource, the following things happen in this order:

  1. A DataListItem instance is created.
  2. The proper template is used to render the contents of the DataListItem. It's at this point that the DataList's SelectedIndex is checked to see whether the ItemTemplate should be used or if the SelectedItemTemplate should be used.
  3. The DataList's ItemCreated event is raised.
  4. The DataListItem's DataItem property is set to the current DataSource row, and the DataListItem's DataBind() method is called.
  5. The DataList's ItemDataBound event is raised.

By examining the above sequence of events, it hopefully is evident why we can't simply set the SelectedIndex property in the DataList's ItemDataBound event and have it work as planned. The reason is because the SelectedItemTemplate has already been applied several steps before the DataList's ItemDataBound event fires. So, if setting the SelectedIndex in the ItemDataBound event handler is too late, where can we set this property?

The answer is that you have to set it before calling the DataBind() method. Namely, after getting your data from the database but before calling the DataList's DataBind() method, you have to iterate through the records and determine the record index of the record that is to be selected. Then, you have to set this property, and only then can you call DataBind(). This approach solves the problem discussed previously because it sets the SelectedIndex property before any of the five steps transpire.

If you want to learn more, check out the in-depth FAQ I wrote on this topic: Setting the SelectedIndex Programmatically.

Happy Programming!

Filed under:
Outputting XML in a Visually Pleasing Manner
16 October 03 02:11 PM | Scott Mitchell

Another XML challenge: given an XML string, like:

<book><title>1984</title><author>Orwell</author></book>

What's the easiest way to display the XML in a friendly, indented way, like:

<book>
<title>
1984
</title>
<author>
Orwell
</author>
</book>

Here is my approach, let me know if you know of one better. Essentially, what I do is the following:

  1. Populate an XmlDocument with the XML data.
  2. Create an XmlTextWriter instance that writes to a StringWriter and set its Formatting property to Formatting.Indented
  3. Save the XmlDocument's data to the XmlTextWriter via the Save() method
  4. Get the prettily formatted XML by calling the StringWriter's ToString() method.

Is there a more efficient way? It seems rather unfortunate to have to load the entire XML in an XmlDocument instance first. I guess one could use an XmlTextReader to read through each node, and then write it to the XmlTextWriter, but I don't see a method that does this for me automatically. Anywho, here's the code I use:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);

StringWriter sw = new StringWriter();
XmlTextWriter writer = new XmlTextWriter(sw);
writer.Formatting = Formatting.Indented;

xmlDoc.Save(writer);
Console.WriteLine(sw.ToString());

Filed under:
Working with XML Strings
16 October 03 10:29 AM | Scott Mitchell

Pop-quiz, hotshot: you have received a payload of XML data in the form of a string from, say, a Web service. Now, you want to perhaps parse this XML data, and perhaps display it in a DataGrid. What do you do, hotshot, what do you do?

Ideally, it would be nice to be able to load the data into one of the many XML-related classes the .NET Framework BCL provides, perhaps the XmlDocument. XmlDocument contains a Load() method, so you think to yourself, "Ok, here's what I'll do:"

// Create a new XmlDocument instance...
XmlDocument xmlDoc = new XmlDocument();

// Load the XML string data...
xmlDoc.Load("Mitchell");

That won't work, though. The XmlDocument's Load() will accept a string input parameter, but it expects it to be either a URL or a file path where the XML data can be found. Drag. The Load() method, however, can also accept a TextReader instance. Therefore, we can load the XML string data into a StringReader instance, (which is derived from the TextReader class), and then pass in this StringReader into the Load() method!

// Create and populate a StringReader StringReader
sr = new StringReader("Mitchell");

// Create a new XmlDocument instance...
XmlDocument xmlDoc = new XmlDocument();

// Load the XML string data...
xmlDoc.Load(sr);

I recently wrote up a FAQ discussing this in more detail. Also worth checking out is this article by Anthony Hart: DataGrids, DataSets, and XML Strings.

Happy Programming!

Update
A bit of searching the docs has revealed that the XmlDocument class contains a LoadXml() method that loads from XML string data. So... I guess you could use that (assuming you don't need to validate the XML upon loading - for that you still need to use the Load() method). :-) However, for things like XmlTextReaders and whatnot, you will still need to use StringReaders for loading XML string data....

Filed under:
Creating Designers for Custom ASP.NET Server Controls
15 October 03 03:36 PM | Scott Mitchell

Over the past few months I have started building a number of custom ASP.NET server controls, something I had only before done once before. What I am finding is that I'm really enjoying the process, in part, I think, because it is a “closer to the metal” programming paradigm than just regular ASP.NET Web application programming. For those who aren't familiar, you can create your own custom Web controls with compiled code. This can be useful for extending the functionality of an existing Web control, or building your own custom Web controls that aren't available with ASP.NET by default. For example, in Easily Adding Functionality to ASP.NET Server Controls I look at how to extend the default Calendar Web control to use client-side script so that the day the mouse is hovering over is highlighted. Some wonderful examples of (free) custom ASP.NET server controls can be found at MetaBuilders.com.

When creating server controls, you can also optionally build a Designer class. The Designer class provides a rich GUI experience in the Visual Studio .NET designer. If you use VS.NET then you are already familiar with the WYSIWYG Design tab - you can drag and drop a Web control, set its properties, and blam-o, the control's visual changes due to the property changes are automatically reflected in the designer.

Unfortunately, I haven't been able to find much online information on creating Designer classes. Yes, there is G. Andrew Duthie's article Adding Design-Time Support to ASP.NET Controls, and there are assorted tidbits I've found on other sites, but nothing incredible comprehensive. The best resource I've found thus far is Chapter 15 of Developing Microsoft ASP.NET Server Controls & Components. (BTW, this book is a must have for anyone serious about ASP.NET server control development.) I've also found it helpful to look at the Designer classes created by other individuals.

One thing that I didn't find out until today (which is neatly tucked away on the last page of Chapter 15 in the aforementioned book), is how to debug Designer classes. If there is a bug in your Designer class, when someone drags and drops your custom server control from the Toolbox onto the Design tab, a little box will appear saying there is some error in displaying the control. That's it! No hint or clues as to what might be causing the problem. Debugging the Designer class, however, is possible, with the following steps:

  1. In the Designer class Project, access the Project's Property dialog box by right-clicking on the Project name in the Solution Explorer and choosing Properties.
  2. Go to the Debugging settings in the Configurations Properties folder and choose the Debug Mode as Program.
  3. Set the Start Application as devenv.exe (you may need to include the path to the file - this is the Visual Studio .NET IDE EXE file...)
  4. Set a breakpoint in your Designer class at an appropriate location...
  5. Hit F5 to start debugging, this will open up another instance of VS.NET
  6. Create a new ASP.NET Web application and add to the References folder the assembly that contains the Designer class.
  7. Drag and drop your custom control from the Toolbox onto the Design tab - you should be taken to the breakpoint in your Designer class.

Also, if you find looking at others' Designer classes as a good education tool, I invite you to check out an open-source project I started up last month called skmMenu. It's an ASP.NET menu control, with full source code available for free, including a Designer class. You can find it on the GotDotNet Workspaces. Also there will (eventually) be two articles about skmMenu up on the MSDN ASP.NET Dev Center.

Filed under:
A "Killer Blog" Directory
14 October 03 11:25 PM | Scott Mitchell

There are a number of directory sites for ASP.NET information. Sites like 123aspx.com, 411ASP.NET, and others provide a directory of online ASP.NET articles and FAQs grouped by category. For example, with these sites it's really easy to find a list of email components, user control tutorials, or pre-built ad management applications. These directory sites do a great job of categorizing and localizing a ton of very useful information interspersed over the Internet.

I was thinking that a killer Web site might be a blog directory for .NET information. There are a number of excellent bloggers out there, putting out invaluable information in their blog entries. But even those bloggers who have the highest signal to noise ratios still oftentimes put non-technical fluff in their blogs, like their latest electronic toys, what book's their reading, or movie reviews. While this is what makes many blogs personable and worth subscribing to, if you are solely interested in .NET information you might find this fluff frustrating.

What I think might be a useful Web site would be a directory of great blog entries that focus specifically on .NET. These could be categorized like general ASP.NET directories, but would instead focus solely on indexing top-notch blog entries.

Do you think such a service would be worthwhile, or should this be delegated to the existing directory sites, including in with their catalogs of articles? Does such a site exist already? I'm unaware of one. I'm contemplating starting up such a resource site, but don't have the time right now. Plus, I have other projects demanding more of my attention which have been neglected more than they deserve. Maybe someone will pick up this idea and run with it, if someone already hasn't, and (most importantly) if the reward is worth the effort...

Filed under:
Building a Challenge/Response Spam Blocking System
10 October 03 04:46 PM | Scott Mitchell

I recently built a challenge/response spam blocking system for myself, quite similar to SpamArrest. Anywho, I wrote up an article on my experiences and my thoughts on challenge/response anti-spam systems. Here is a snippet to whet your appetite!

I am no longer hesitant to give out my email address on the Internet - it's mitchell@4GuysFromRolla.com. Of course, I've never been too hesitant to publish my email address, it's on literally thousands of Web pages on the three Web sites I run (4GuysFromRolla.com, ASPFAQs.com, and ASPMessageboard.com), which helps explain why, prior to October 6th, 2003, I was receiving over 100 spam emails per day on one email address.

Spam has been a major problem for me for the past several years. With each passing year the number of spams I received has more than doubled. Assuming this continued exponential growth, I estimated by 2010 I would be receiving over 61,000 pieces of spam in my Inbox per day. That's over 42 pieces of spam per second. Of course, these estimations are more for a grin than to be taken seriously, but the fact remains: prior to October 6th I was inundated by a daily torrent of spam.

"What happened October 6th," you ask? Did I shut down Outlook for good? Nope, I employed what seems to me the only plausible way to end spam but still receive important email: I built a challenge/response (C/R) spam blocking system. A C/R spam blocking system works by allowing emails from a list of "trusted" email addresses (a white list), and refusing emails from a list of "black list" emails. When a new email arrives, the email's From (and possibly To) address is checked to see if it belongs in the white list or black list. Email messages from white listed addresses are downloaded by my email reader, while black listed emails are automatically deleted. When a message arrives from a sender who is in neither the white nor black list, the person is sent a challenge email, with directions on how to respond. The response process is simple, namely that they visit a Web page and enter a password. Once this step is completed, the person is added to the white list. Until this step is performed, their email is in limbo.

The whole idea behind a C/R spam blocking system is that the spammer will not take the time to respond to the challenge email, while people who are interested in contacting me will respond so that they can be added to the white list. This response is a one-time affair, and only takes a moment, so (in theory), anyone who is interested in contacting me won't mind the brief step they need to perform prior to emailing me. There are currently a couple of commercial companies that offer spam control via C/R. The one I have heard most talk about is SpamArrest, which charges a reasonable monthly fee for their service.

This article, I think you will agree, is a bit lengthy. It is divided up into three sections. In the first part, I examine the C/R spam blocking system I built, offerring advice and lessons learned to others who may be interested in implementing such a system. In the second section I evaluate the success of my C/R spam blocking system. Finally, in the third part I discuss both the negatives and positives of C/R spam blocking systems.
[Read the Rest of the Article!]

Filed under:
A .NET Performance Challenge
01 October 03 11:39 AM | Scott Mitchell

Every Wednesday I email out the latest article on 4Guys (usually an ASP.NET piece) to those who have signed up for the WebWeekly newsletter. Last week's article was titled Creating XML Documents with the XmlTextWriter Class, and looked at using XmlTextWriter to create XML documents. (You can see a live demo of the XmlTextWriter in use here.) Anywho, after the email went out I got an email from Michael Balloni, the lead software engineer at Steamload.

Streamload is a heavily trafficked Web site that acts as a place for users to store digital content. Users can upload files to Streamload's computers and then download the files or email their files to other Streamload users. To put it mildly, there's a lot of 1s and 0s flying through those pipes leading into Streamload. Since Streamload is located here in sunny San Diego, I've had the opportunity to meet with Michael on more than one occasion. He's showed me around and shown me the code and architecture behind Streamload. Currently, Streamload is still a classic ASP shop. Michael has a rich and efficient architecture built up using classic ASP and VB and C++ COM components that emphasizes efficiency over “the latest technology.” (By the way, Michael has written some articles and user tips on 4Guys...)

Anyway, with that background on Michael and Streamload, you might not be surprised to find out that after reading my article on the XmlTextWriter class, Michael emailed me asking about the performance of XmlTextWriter in comparison to his lightweight XML creating VB6 COM object. His precise comments:

I reckon if you do a straight port to your bloated/overwrought object mess (.NET) that the code won't fare too well...but I also reckon you're crafty enough to rewrite the code to be at least as fast as my VB6 code. I should certainly hope so, don't you think?

A challenge? :-) Unfortunately, my free time is less than ample as of late, so I decided rather than to take this challenge upon myself, I'd offer it up to the ASP.NET/.NET community at large: can you use .NET to beat Michael's implementation? You can get your hands on Michael's VB6 component here. Michael's challenge stands as follows:

Write .NET code to beat my XmlEncode function's "Test Encoding" performance, and use whatever .NET/ASPX method to beat the "Test Throughput" performance (maybe XmlTextWriter will work?) And man, if nobody can do that, jeez.

Anyone up for the challenge?


Personally, I would wager that Michael will win the challenge. Consider, for a moment, this article: XSLT Performance in .NET. In this article author Dan Frumin examines the performance of the MSXML COM component vs. the XslTransform class for performing XSLT transformations. The only speed advantage XslTransform provides is in creation of the object - there is a significant overhead in initializing the COM component in a .NET environment. But, after this initial cost, MSXML kicks butt, especially with larger XML files.

Am I surprised? No. .NET adds on another layer of abstraction onto a programming paradigm already rife with abstractions. The .NET Framework serves as a layer of abstraction, just as the Win32 API serves as a layer of abstraction, just as high-level programming languages serve as a layer of abstraction, just as assembly language serves as a layer of abstraction. .NET, like the Java platform, is another encompassing layer in a slew of layers. Is this a bad thing? Taking a “performance-only” view, then, yes, any layer of abstraction robs you from the sheer performance typing in 1s and 0s can afford. But, from a development standpoint, from looking at the bottom-line not just as how many operations per second, but how many man-hours it takes to create the program to run those operations, layers are a Good Thing.

End conclusion: I expect those who do take on the challenge Michael outlines will have a hard time beating the fine-tuned VB6 COM code. But, in the long run, it really doesn't matter.

Filed under:
More Posts

Archives

My Books

  • Teach Yourself ASP.NET 4 in 24 Hours
  • Teach Yourself ASP.NET 3.5 in 24 Hours
  • Teach Yourself ASP.NET 2.0 in 24 Hours
  • ASP.NET Data Web Controls Kick Start
  • ASP.NET: Tips, Tutorials, and Code
  • Designing Active Server Pages
  • Teach Yourself Active Server Pages 3.0 in 21 Days

I am a Microsoft MVP for ASP.NET.

I am an ASPInsider.