User login


Welcome to Knoxbloggers.Com!

Knoxbloggers.Com is the official homepage for the Knoxville Blogger's Meetup Group - a Knoxville area group that meets to discuss tools and services available to bloggers to help them blog.

We welcome you to check out the site, and if you're in the Knoxville Area and are interested in blogging, please sign up for an account and join us at the next meeting. Below is a selection of what members are blogging right now!

Member Blogs

Michael Neel's picture

ORM talk at CodeStock Open Spaces

One thing I'm hearing from a lot of people who attended CodeStock last Saturday is how well the open spaces "track" was.  This is one area I can't take any credit for, my only role in planning open spaces was requesting a room from the college; all credit for success goes to Alan Stevens the facilitator.

An Open Spaces conference is explained as the "un-conference" - a very hippy, free flowing conference where the sessions self organize and the topics are chosen by the attendees.  This in contrast to a traditional conference of set speakers and topics.  Each have an advantage; an open space isn't the best place to get a first look at a technology but once you've used a technology an open space is a great place to discuss with others how it should be used.

Rather than choose one format, CodeStock featured both.  This worked out better than I could have imagined because it mixed two camps - the open space people hung out with the "straight laced" conference people.  This created a stage for some great conversations with all views represented and an exchange of ideas can commence.  Wally McClure was breaking in a new Flip, and managed to capture an ORM discussion for the latest ASP.NET Podcast - I would have loved to have been there, but I was fighting gnats at the time.

More video formats available at ASP.NET Podcast

The Codestock Wrap-up

Codestock has finally come and gone.  After large events like this, I am always amazed at the amount of time and energy used to plan and host such an event as opposed to the speed at which the event actually passes by.  Two days after the event, I still keep feeling that there is something that I need to be doing in order to prep for Codestock, lol.  Nonetheless, I have to say that I had a blast during the entire event.  I was introduced to many new ideas, many new people, and simply had a whole lot of fun. 


So, here is my experience in a nutshell...

Sessions Attended

I had the privilege to attend 2 sessions at Codestock, both of which were excellent:

Rachel Appel and Dynamic Data 

Rachel did an awesome job in giving an overview of Dynamic Data.  Unlike many of the other demos over the subject, she not only spoke about how to use it / make it work but also added a practical slant to it.  Also, Rachel has a very unique and awesome sense of humor, which really made the presentation a lot of fun.  Despite the fact that Rachel was having a 'Lisp' problem, I really enjoyed her session.  Great job!

I have to say that I am pretty excited about Dynamic Data and I sincerely look forward to start playing w/ some of the new bits released today.  Particularly, I am very intrigued by the support for type templating on the website level.  Once I saw how Dynamic Data was accomplishing this, I wanted to slap myself for not thinking to do this before hand.  Of course, reduction of physical files due to Routing and the use of scaffolding are cool features as well.

My only main concern w/ Dynamic Data is whether or not it will allow me to a-la-carte its features.  I am not a huge fan of scaffolding and I think, in a perfect world, I would like to see something of a mix between what Dynamic Data promises and how I use WebForms today.  I do not want to be restricted to a narrow approach with my web apps.  I will have to blog about this at a later date.  :)

Open Spaces moderated by Alan Stevens

This was my first open spaces event and, admittedly,  I was a bit skeptical as to how effective this approach would be.  After participating in this event, it suffices to say that I am a complete convert.  Open spaces is an excellent way to learn new concepts and ideas from one another.  I can't think of a precise way to explain open spaces rather than to simply say that it is an open conversation between peers that share mutual respect for one another (usually about a predefined topic).   Due to this, you feel very free to present ideas, critique other person's ideas, and learn in the process. 

While I was there, we discussed ideas ranging from planning sessions for user groups to why a MacBook is a viable choice for .Net devs to how to handle development needs in a unsympathetic workspace.  As you can tell, the range of topics were far and wide, but they were extremely useful in content.  Of course, we also had the obligatory Twitter session... ;)

Alan did an excellent job moderating the event, encouraging contribution by all persons in the room while being very mindful of the topic at hand. It seems as if this would be a difficult task, as you would want to make sure the conversation had direction but that it was not inhibited by such direction.  Great job, Alan.

Sessions Given

I agreed to take on 2 sessions to present at Codestock.  The first session was a revamped session of my Asp.Net Provider speech that I spoke to the ETNUG earlier this year.  Even though the presentation was one that I had given quite a while back, it certainly was not dated.  One thing that I particularly like about this session is that it focuses more on design principles and patterns rather than any specific technology.  To be honest, I simply use the Asp.Net Providers an avenue to look into the concepts of integrating design patterns within your apps and the benefits of doing so. 

All in all, the session went pretty well even though I feel that I could have done better.  I felt that my main flaw was launching into the session too fast.  I kept having to force myself to slow down and not inundate the audience w/ information.  Besides that, I spent quite a bit of time reworking my original slides, attempting to take a BBP approach and introducing consistent themes.  (I might have gotten a little carried away on the themeing, lol)


My second session was something of a wildcard.  I had the privilege of co-hosting a session w/ Mike Neel concerning what the new features in .Net 3.5 SP1.  The session title was .NET3.5SP1BETA1BBQ in homage to the increasing tendency to create finer denominations of release status.  Considering the fact that we had next to zero collaborative prep time and, in some cases, we were simply hanging on by the seat of our pants, I have to admit that we did pretty good.  We made it through the session with only minor organization issues and, more importantly, the session felt more like a running conversation rather than one person rambling on about some topic or another.  I think the audience was better served by there being 2 presenters in that they got a good look at what was new, but from two different perspectives. 

Other Stuff

Finally, there were quite a few other highlights to my day at Codestock. 

First off, I got to meet a ton of tweeple of whom I had yet to meet in person.  On top of that, I got to meet a slew of new folk as well as speak w/ some old and dear friends that I had not seen in a while.

After the closing session, some of us went on down to enjoy the Codestock after party.  Mike arranged for a live band to play for us by the name of Hanover Fist.  They rocked!  They reminded me of a blues-y Lynard Skynard and really did an excellent job.  IIRC, they just released a new cd, which I will certainly be tracking down soon (as well as a t-shirt, I hope).


In conclusion, Codestock totally rocked.  Mike Neel, Wally McClure, and Alan Stevens did an excellent job in organizing the event.  Particularly, Mike deserves recognition for just about killing himself in order to make sure all the finite details were in place.  Also, Wally of Scalable Development was kind enough to make a huge contribution towards the closing session raffle, increasing the amount of excitement for the event.  In other words, thank you, Mike, Wally, and Alan, for making this great event happen.

I left Codestock w/ about 10,000 different ideas and concepts to try and, hopefully, left a few behind for others.  All in all, it was an excellent event and I look forward to next year!

Take care.

On a side note, if you live in or around the Knoxville area, be sure to attend the East TN .Net Users Group (ETNUG).  We are an organization that meets on the last Tues of every month in order to learn about new technologies, socialize, and just have a good time.  It is a great way to meet other developers as well as learn about the latest and greatest of today's technologies.
DylanW's picture

CodeStock Wrap-Up

CodeStock Developer's Conference - Knoxville, TN

I just got around to posting my notes from CodeStock for my coworkers, so I figured I'd post some of the highlights here too.

Mike, Alan, and Wally did an excellent job putting this together. I was surprised that, for a first year conference, we had such a large turnout and yet everything ran really smoothly. (If it didn't run smoothly, they at least did an excellent job of faking a well-orchestrated event.) It wasn't quite as big as DevLink, so we may end up being the MTAC to their AWA*. :)

Behind the scenes, I'm very happy with the commitment to selecting local speakers. I think this is going to be one of the things that sets CodeStock apart, especially as it grows. It shows a commitment not only to the industry in our area, but the people as well. I feel there's a lot more celebrity than there needs to be in the software development world, so a locally-focused conference is a refreshing trend.

Here's a rundown of the sessions I attended:

  • 10 Open Source Tools You Should Be Using - Good talk, even though I'm not much of an MVC or TDD guy. Loved the fact that James presented alternatives to each of the applications he discussed. The talk sold me on checking out Castle ActiveRecord for projects where I can't use LINQ to SQL, as well as checking out SQLite if I ever need to write a desktop application with a local data store. A full list of these tools are on James's blog.

  • What's This XNA Thing? - I think my coworkers looked at me funny when I said I wanted to attend this session. I haven't touched XNA since I walked through a Pong tutorial in the 1.0 release, but this was a pretty good motivation to look at it again. I don't think Chris has posted slides yet, but most of the resources he listed can be found on the Twin Cities XNA User Group site.
  • SharePoint Developer's Survival Guide - If you're doing any SharePoint development, this talk was essential. You can find the slides on Doug's site; there's really too much to cover. (I like the fact that he supported my WSPBuilder bias.) He came from the same angle I used in my SharePoint talk, except developer-oriented instead of more administrator-/manager-oriented: these are the pitfalls, and here's how you avoid them. The most telling thing in his speech: "it takes at least 2 years to make a good SharePoint developer."
  • httpModules and httpHandlers - I've written a few handlers, but this speech gave me a better understanding of modules, as well as a lot of other uses for handlers I hadn't considered. Chris posted his content from CodeStock on his blog.
  • Much Ado About Testing - Again, I'm not a TDD guy but I am sold on unit testing. I'm also not quite up to speed on concepts like mocking, so this session filled me in quite a bit. Not quite sure I want to switch from NUnit to MbUnit yet, I haven't run into a case where mocks would actually be beneficial to me**, and Watin really sounds too complicated for my purposes right now. But it's nice to know that it's out there.

For any .NET developers who enjoyed CodeStock--make sure you come and support the East Tennessee .NET User Group. ETNUG was the driving force for a lot of the publicity, speakers, and sponsorship; supporting the group can only help make the conference better next year. If you enjoyed the local speakers at the conference, this is the place to get even more (including me, at the end of this month, speaking on SharePoint).

There was also some talk of doing some Open Spaces during one of our future meetings--I don't know whether that will come to pass, but from what I heard about the Open Spaces (I didn't make it to any of the sessions), it would be a great alternative to the typical presentation.

* Translation for non-anime geeks: AWA is a bigger convention than MTAC, but if you're in the area, it's well worth attending both.

** Of course, it shouldn't be any secret that I test my data access.


Michael Neel's picture


Warning: this is going to be a grilled cheese post.

I woke up this morning, amazed there is an August 10th.  I mean, I knew there was a full August this year, but for the last two months I haven't given much thought to any date past August 9th, the date of CodeStock.  I've pretty much wasted the whole day - slept in, made a run to Sonic, played Rock Band with Cicelie and the girls and made it through another level in Bad Company.  I figure (hope) many people will blog about CodeStock, so instead of giving the overall picture, I'll tell you what my day was like.

5:30 am Alarm goes off.

6:15 am I wake up, realizing that somehow I fell back to sleep.  I need to be at Pellissippi by 7am and it's a 20 minute drive.  The truck isn't loaded with the 4 boxes of shirts, 3 boxes of bags, 2 boxes of books, and many other boxes of giveaways, and misc. needed items.

6:45 am After an amazing display of speed and strength, Cicelie and I are on the road to Pellissippi with a fully loaded truck.  I even remembered to get dressed.

7:05 am Glenn Zahn and the RecruitWise are already at the Performing Arts Center (PAC), as well as Gabriel (a volunteer).  We unload and begin setting up the registration area.  Catering is setting out juice and coffee, I grab a badly need cup.  This would be my first of 5 cups of coffee that I grab, take one sit, set down somewhere and can't find it later.

7:30 am Cicelie and Lisa (of RecruitWise) have the registrations down to a science.  I keep trying to help, but I'm just making things worse, so I setup the giveaways on stage.  I'm also getting a question every two minutes, but I'm delegating tasks as much as I can so my constant distractions don't seem to be a problem.  I have an awesome team of volunteers.  Thanks Cicelie, Jim, Gabriel, Crystal, and the RecruitWise team.

8:05 am At 7:55 it looked like there was about 20 more minutes of registrations - I underestimated how fast Cicelie and Lisa were, because at 8:00 there was no one in the line.  We start only 5 minutes off schedule.

8:20 am My opening over, I hang around the ticket booth.  A number of small issues seem to work themselves out.  Example, Alan needs power strips for Open Spaces, Wally calls on his way in asking if we need anything - so I tell him power strips.  There is something Zen going on, and I'll not dare question it.

8:40 am Scott Spradlin is here from INETA to film interviews on the "making of" CodeStock.  I help him setup a T-shirt for a back drop, and then do a short interview.  Not thinking of Murphy, I talk about how well planned everything is.

9:00 am The last 20 minutes felt like three hours - that's the speed difference in the day from the morning registrations.

9:30 am Right on time, attendees are in their first sessions.  I grab my camera to snap photos of the speakers in action.  I fail at getting a shot of Amanda Laucher without her noticing.  I also get flipped of by James Bender.  I have photos to post later.

10:30 am It occurs to me that offering to help Nathan Blevins fill in for Wally McClure's session has put me in a session right before lunch (also known as the next chance for panic).  I fill Glenn in and ask him to lead setting up a "human chain" to direct people to the cafeteria for lunch.

12:00 pm Session over, it went okay but I'm feeling it sucked hard.  This is mostly because this was an ad hoc session and I'm used to my highly planned sessions.  Having never rehearsed the session together, the handoff's between Nathan and myself flowed almost as smooth as wet cement.   The content is good however, and we can turn this into a pretty good talk in the future.

12:05 pm I expected to find a long line of people waiting for lunch, and some catering crisis in the kitchen.  What I found was everyone had their lunch and was sitting down eating and having a good time.  This was the best execution of a lunch I've ever seen at a community conference - and I had little to do with it.  I grab a box and talk to a few people before going back to the open spaces room to eat.

12:45 pm The open spaces room is attracting a lot of people during the lunch hour.  I get back to the ticket booth and round up 3 other people to hear out to the after party tents so we can setup tables and chairs.

1:05 pm The running track around the pond at Pellissippi is covered in an amazing amount of crap.  All kinds of crap: bird crap, dog crap, duck crap.  I see people running on this track all the time and think to myself if running on crap is as healthy as these people think it is.  I walk beside the track in the grass.

1:10 pm The tents are filled with about 30,000 gnats.  Freaky ones I've never seen before - they look like a mosquito but instead of a sucker for a mouth they have two little fuzzy balls.  They don't bite, but no one would eat a hot dot with these guys around.  They appear not to have come from the pond around the tents, but from the stack of chairs left in the tents.  There are also a few wasp nests under the stairs leading up to the stage.

1:20 pm Glenn and crew will finish setting up the chairs, I'm off to buy an arsenal of anti-gnat weapons of mass destruction.  On the way out I run into John Kellar and Brian Prince.  John organizes DevLink and Brian organizes CodeMash - the two "biggies" in our region.  We joke a bit and then Brian mentions Kentucky Day of .Net is in 3 weeks - both John and I (who will be speakers at the event) are shocked it's so soon.  Just like I didn't see past August 9th, John's not thinking past August 22nd and DevLink.  I'll call this condition "conference blindness."

2:45 pm I return with my gnat WMDs and launch a full scale invasion with outdoor foggers and citronella candles.  I also drop 3 wasp nests before I run out of wasp spray (the kind that shoots a stream).  The cans of fogger say they kill wasps, and there are a few wasps that escaped, so I hit them with the fogger.  Do not use a fogger on a wasp unless you really want to piss it off.  Axiom: if it doesn't kill on contact, don't use it on a wasp.

3:00 pm I call Cicelie to she if she can send out a few volunteers to watch the tents for an hour or so.  I have 10 citronella candles burning under two tents and I think it's against fire code to leave them unattended (probably against common sense too).  The band will be there to setup at four, and they can come back to the PAC then.  She finds someone from RecruitWise (whose name I can't recall) to relieve me.  Update: His name is Eric.

3:30 pm Things are quiet from now until closing - I mostly hang around the registration desk and chat with passing speakers.  Nathan juggles Microsoft stress balls, and I learn Dave Redding called attendees jackasses, one guy an asshole, and gave my ex-wife beer all during his session.  I make note to attend Dave's sessions in the future.

5:00 pm Closing, and raffle off of the goodies.  I pretty much just rattle off ticket numbers for 30 minutes, and let people choose their prize in a "first come / first choice" fashion.  We picked up so much extra items to raffle off during the day it's crazy - including a Halo 3 Legendary Box Set (the one with the Master Chief helmet) from Brian Price and Microsoft which went second to the MSDN subscription donated by Wally through Scalable Development.

I had five copies of Petzold's Turing book to give away, and was amazed at the level of interest among speakers to win the book.  I'm pretty sure one speaker (I won't name them) stole the book off the stage during the raffle.  There were some speakers opting not to take anything when they won, letting me draw another number, so a swap could have been done instead of theft.  I want to find out the rest of the story - what happened, and was the book really that sought after?  It's a great book, don't get me wrong, but it's a little crazy to think it would cause such a commotion.

Update: Got the whole story, no thefts just some mixups, and the Petzold book was really in demand.  I guess I did a good sales job holding up the title and talking about my review!

5:45 pm Steve Andrews, Cicelie, and I do room checks to make sure nothing is wrong with any of them and clear out trash.  I'm impressed that the rooms need very little cleaning - people took care of the place.  I stop by as Scott is finishing an interview and do a short interview on end of the day thoughts.

6:10 pm I arrive at the CodeStock After Party, slightly late.  My biggest blunder of the day was forgetting to tell everyone there was food (hotdogs, chips, and drinks) at the party.  About 20 people are there, looks like many had left to eat.  Hanover Fist put on a great show, and I got up and sang "Oh Well" by Peter Green era Fleetwood Mac.  I dedicated the song to my MVC brethren.

7:45 pm The band finishes the last song, and people start heading home or to Alan's "After After" party.  I tell people I plan on getting to Alan's around 9:30.  I stay behind with Cicelie and my brother Willie to fold up chairs and tables.  I thank the band and drive home.

9:30 pm I've been trying to talk myself into going to Alan's party for the last 30 minutes, but I give in.  Cicelie, my daughters, and I share some ice cream.  I went to bed right after.

DylanW's picture

Seriously, WTF?

Not sure if some new worm or exploit has exploded upon the internet, but I'm seeing some really bizarre hits on my site today. Requests for stuff like:


What is that, an SQL injection attack for SQL Server? Which might be quite the issue if my site wasn't hosted on a Linux server. (Or, quite the issue if I was running on a webhost that hosted SQL Server on the same box as web with no firewall... which I suppose would be its own WTF.)


DylanW's picture

SharePoint Gotcha: Debugging Code Blocks and Event Handlers (or the lack thereof) in Site Pages

Here's a problem one of the other developers here ran into--if you create your own site pages in SharePoint, you're bound to see an error like this pop up:

An error occurred during the processing of /mypage.aspx. Code blocks are not allowed in this file.

... wait, what?

Yup, that's what it says. You can't use code blocks in ASPX files that are stored in SharePoint. No <% Response.Write("Hello World!") %>. No <%# Eval("Name") %>. As an added bonus, <asp:Button runat="server" ID="MyButton" OnClick="MyButton_Click" /> doesn't even work because it declares an event handler.

That's not really the gotcha here. This is well-documented in Inside Microsoft Windows SharePoint Services 3.0: check page 81, if you're following along in your books at home. SharePoint has a very good reason for this security setting to be there: users can create and modify ASPX files that are stored within the SharePoint database. So, if you could run arbitrary code within an ASPX file, a user with no access to the server could potentially run malicious code.

So where does that code go? Well, it goes in the *.cs or *.vb code-behind file. That means to declare an event handler, you're going to have to do something like this:

protected override void CreateChildControls(){    base.CreateChildControls();    SaveButton.Click += SaveButton_Click;    CancelButton.Click += CancelButton_Click;}

And rather than displaying data in a GridView or Repeater using Eval() or Bind(), you have to give it an OnRowDataBound or OnItemDataBound handler. So that means, rather than doing this:

<asp:Repeater runat="server" ID="MyRepeater">    <ItemTemplate>        <asp:Literal runat="server" Text='<%# Eval("Name") %>' />    </ItemTemplate></asp:Repeater>

You do this:

protected void MyRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e){    // Make sure we have a data item in this row    if (e.Item.DataItem == null) { return; }    // Convert the data item to its original type    DataRowView dr = (DataRowView)e.Item.DataItem;    // Find our literal control in the current repeater item    Literal NameLiteral = e.Item.FindControl("NameLiteral") as Literal;    // If it was found, set its value    if (NameLiteral != null) { NameLiteral.Text = dr["Name"].ToString(); }}

I can imagine you're griping already. It's easy to see the security reason for doing this--you don't want users to be able to run arbitrary code on your server. But it's so freaking complicated. (Well, it is until you get used to the idea.) But as I said, that's not the real gotcha here. So what is the point of this post?

The real gotcha here is that this doesn't seem to be a default security setting, at least in the development environments we're using. (Andy's using a VirtualPC image he set up himself; I'm using Microsoft's WSS3 VirtualPC image.) We only ran into this issue after he tried to install a project on the client's server.

I don't think we've figured out exactly what turns on this security setting in SharePoint configuration, but I have found out how you can force your development environment to throw these sort of errors. All you have to do is dig into your development site's web.config file and add the following node:

<configuration>    <SharePoint>        <SafeMode>            <PageParserPaths>                <PageParserPath VirtualPath=”/*” CompilationMode=”Always” AllowServerSideScript=”false” IncludeSubFolders=”true” />            </PageParserPaths>        </SafeMode>    </SharePoint></configuration>

Once that's done, you can now catch yourself using stuff that's not allowed in ASPX pages before it gets to your client's server.


daryl's picture

Happy B.C. Day

It turns out that I’m in Victoria, British Columbia for work this week. When I planned the trip (at the last minute), I didn’t know that Monday was a Canadian holiday. As one of my American coworkers is here as well, it’s really not that big a deal; we’ll work in peace without all the usual water cooler chatter about moose and that most riveting sport curling (ok, so hockey is probably the more obvious sport choice, but curling dominated the TV when I was last in town).

I learned today that B.C. Day isn’t just a laze-around-the-house holiday but is one that Victoria, at least, does up right. Tonight, the symphony was playing from a barge in the harbor, and tomorrow, Vancouver resident (or native?) Sarah Machlachlan is the headliner for a free concert. I was tired this evening (still on Eastern time) but had thought about walking down to the harbor to hear the symphony. When I read online that they traditionally play the 1812 Overture as part of the event, the deal was sealed (it’s a rousing tune that always makes my barnacled old ticker stir a little). So walk down there I did, and I really enjoyed it.

It’s just a block from my hotel down to the harbor area. If you follow the road around the perimeter of the harbor, you pass The Empress, a venerable old (I think very old) hotel with walls covered in something green (ivy or something of that ilk). I think a coworker told me during my last visit that the hotel is slowly sinking into the ground. Then you keep walking around until you get to the Parliament building, which is hard to miss because it is outlined in white lights (like some houses at Christmas). The barge or whatever the symphony was arranged on was basically a straight shot out the front door of the Parliament. There were people lining the streets, sitting on the harbor shore, and filling the lawns of those two neat old buildings.

By the time I got down there, it was starting to get a little dusky, and it was neat to watch the tangle of boat masts swaying in the breeze (I won’t be so fanciful as to suggest that they were dancing to the music, though for a moment I was tempted). The weird thing is that as I approached, the song I heard was “Home on the Range,” and it was followed by “Clementine” and then by a song I recognized and that I heard them announce with “Appalachian” in the title. These all seemed distinctly American to me, so I amused myself for a minute thinking about what a nice welcome party Victoria had thrown me.

I wandered around listening to the music and watching people and generally enjoying the atmosphere. People were dancing to the music and smiling unself-consciously and really having fun, and it was fun to be part of it.

The rendition of the 1812 Overture wasn’t the best I’ve ever heard, but then half the sound was no doubt carried away by the 100 yards between the symphony and me, so maybe I’m not being fair. Toward the end of the song, when cannonfire is appropriate, fireworks were shot off in the harbor, and the pealing of bells could be heard from a belltower sort of between The Empress and the Parliament, and that was a neat addition.

As the concert wrapped up, people started heading back toward downtown (where my hotel is), and I floated with them. A drum and bagpipe group (complete with kilts and big furry hats) was marching in the street and started playing Amazing Grace as I walked away. Just a couple of blocks down from my hotel on the main drag, a percussion group had set up and was playing some really neat, lively stuff that had more people dancing in the street.

It was a neat night, well worth venturing out in spite of my tiredness, and I can’t help hoping that some of tomorrow’s festivities are evening ones so that I can attend.

Michael Neel's picture

Using LINQ to generate HTML

image I hate seeing code mixed with markup.

Seeing a template page with <% if(show) { %> makes me want to claw my eyes out.  Seeing String htmlTitle = "<h1>" + title + "</h1>" causes me to vomit up a little something in my throat.

Mixing code with markup is not a magic chocolate and peanut butter combination - it's a volatile cocktail of vinegar and baking soda waiting to explode your application to tiny Server 500 Error giblets.

The time comes however when we find ourselves needing to generate some well formed HTML in code, and I found myself in just such a position last night adding the agenda to the CodeStock website. (Less than one week away now!)

Background: On the CodeStock site, the speakers and sessions list lives in an XML file.  The agenda page has a grid of session times and my task was to fill in each session "cell" with the session planned for that room and time.  I wanted to link to the full session and also list the speaker's name in the cell.  In the XML I have created Key elements that are used as HTML anchors in a link to a session.  It's all very low tech, simplistic goodness.  An example of the XML for a speaker:

<Speaker>    <Key>Brownell</Key>    <Name>Steve Brownell</Name>    <Website></Website>    <Photo>~/Speakers/SteveBrownell.png</Photo>    <Bio>        Steve is the manager for research and development at AllMeds in Oak Ridge, TN.  Steve        has been programming one thing or another for over twenty years.  AllMeds makes and        sells a commercial software product which is an electronic medical record system.  We've        been .NET based since 2000.  AllMeds is a VB.NET shop at heart, but the AllMeds system spans        many areas of Windows development.    </Bio>    <Session>        <Key>Hobbled</Key>        <Title>            The Hobbled:  There And Back Again, or Code Automation:  how I made it from the            presentation layer to the database and back.        </Title>        <Abstract>            Stop writing code, and start writing code that writes code.  There's never been more            choices to help you automate the creation of the data object layers immediately above            the database.  Writing class factories and data access classes is boring, time consuming            and wastes valuable time with expensive developer resources.  This course will examine            two current approaches:  using a template engine and programming with the CODEDOM.  We'll            also briefly discuss other ORM techniques like LINQ to SQL Classes.        </Abstract>        <Level>200</Level>        <Technology>VB.NET, C#, LINQ, SQL</Technology>    </Session></Speaker>

(Steve was our CodeStock Speaker Idol winner, and I enjoyed seeing System.Codedom in action; something I'll be playing with and posting on in the future thanks to Steve!)

LINQ to XML, and the new "X" classes that come with it make working with XML as easy as it should have always been.  Armed with LINQ, I decided that putting <%= SessionInfo("Hobbled") %> was something I could live with (had this been a larger site that needed to live longer than August 9th, I would have opted for a user control <CodeStock:SessionInfo Key="Hobbled"/>).  My first LINQ expression looked something like the following:

var info = (from s in speakers.Descendants("Session")            where s.Element("Key").Value.Equals(SessionKey)            select new {                key = s.Element("Key").Value,                title = s.Element("Title").Value.Trim(),                speaker = s.Parent.Element("Name").Value            }).First();

This yields a very useful info object with just the information I need.  *If* I was in a hurry, and didn't mind a little vomit, I would follow on with the following:

String hmtl = String.Format("<a href='{0:s}' title='{1:s}'>{2:s}</a><br />{3:s}",    new object[] { ExpandURL("~/Pages/Agenda.aspx", info.key),                   info.title,                   info.title.Length > 30 ? info.title.Substring(0, 27) + "..." : info.title,                   info.speaker });

Why do I despise this so much?  It's not easy to read, and it can become cumbersome to change.  ASP.NET has a collection of server controls just for generating HTML, intended for use in user controls but they are not limited to user controls alone.  To generate the html above would look something like this:

HtmlAnchor aHref = new HtmlAnchor() {    HRef = ExpandURL("~/Pages/Agenda.aspx", info.key),    InnerText = info.title.Length > 30 ? info.title.Substring(0, 27) + "..." : info.title,    Title = Title};HtmlGenericControl div = new HtmlGenericControl("div") {    InnerText = info.speaker};StringBuilder html = new StringBuilder();using (StringWriter sw = new StringWriter(html)) {    using (HtmlTextWriter hw = new HtmlTextWriter(sw)) {        aHref.RenderControl(hw);        div.RenderControl(hw);        hw.Close();    }    sw.Close();}

There are times when working with parts of the .Net framework I have wonder if some Java types didn't design the class.  The mess here to render the HTML is one of those times.  The lack of a RenderControl that returns a String is the problem - thankfully we now have extension methods to fix the framework, but that's another post.  No matter how much I hate markup in the code, I cannot endorse this version over the vomit inducing first solution.

It occurs to me that HTML is (or was once) fundamentally XML, and I can return XML from my LINQ expression.  In fact, this is what LINQ is about - not just getting the data you want, but getting it in the format you need.  Here is the new LINQ query:

XElement info = (from s in speakers.Descendants("Session")                 where s.Element("Key").Value.Equals(SessionKey)                 let key = s.Element("Key").Value                 let title = s.Element("Title").Value.Trim()                 let shortTitle = title.Length > 30 ?                     title.Substring(0, 27) + "..." : title                 let session = new XElement("a",                              new XAttribute("href",                                  ExpandURL("~/Pages/Agenda.aspx", key)),                              new XAttribute("title", title),                              shortTitle)                 let speaker = new XElement("div", s.Parent.Element("Name").Value)                 select new XElement("span", session, speaker)).First();

This may not seem to some as better.  I myself have trouble looking at most LINQ expressions, but as I'm learning to Thinq Linq I'm seeing that writing the LINQ expression is where the power lies, not in the syntax.  The mental dialog goes something like this:

"Okay, from my list of speakers I want a session where the session's key matches SessionKey.  Now, let me grab some fields I need, first the key, then the title which I need to trim off excess whitespace, then let's make a short version of that title since Steve's title is so long - love that title though.  I'll need an link tag for the session; set the href and title attributes, and then add the speaker's name in a div tag so I get a cheap line break.  I'm really in XML not HTML, so I'll need a root node and a span tag will work without affecting layout, and I'll add the link and div tags as children."

Writing LINQ like this I feel much closer to the problem I'm trying to solve, and not bogged down by syntax.  There is still some moments I'm thrust back to code, such as the use of First() to select only one result.  I'd like to have a "select first" option in LINQ expressions instead of just the extension methods. 

Is this something I'll be using now every time I have this problem?  Not sure yet, but it's another "tool in the box" I'll keep around and use when it feels right.

DylanW's picture

On Presenting

I just finished a presentation tonight at ETNUG called "SharePoint Sucks!" The presentation was my entry into Speakers Idol, where people who weren't selected as speakers for Codestock session could compete for one last remaining session. Didn't win, but it did net me the presentation at the August ETNUG meeting.

Incidentally, for those interested, here are the links I referenced as resources:

The topic, contrary to its name, was about when to use and when not to use SharePoint. (If you really want to know where the title comes from, go through the comments on some of my SharePoint posts.) It's been quite a while since I've had to present anything, so I've been critiquing the whole experience.

One suggestion I received is to ditch the "Intro to Windows SharePoint Services 3" topic I originally submitted, and go with a continuation of "SharePoint Sucks!" for August's ETNUG meeting. I'm not completely comfortable with this idea, because I don't feel that approach is quite my style.

On the other hand, I have found out that I'm much more comfortable at Q&A and discussion than I am at presenting all my own stuff. I think it's because I like thinking inside the box, so to speak. Q&A forces me to tackle the questions that people need to know rather than trying to do an overview that's simultaneously broad and deep. In turn, this keeps me from overanalyzing details or going off on tangents. Extending the "SharePoint Sucks" talk should naturally lead to better discussion. (Maybe.)

So I'm kind of at a loss as to which way to go for the August meeting right now.

I noticed an interesting side effect after presenting that I'm not sure I like. Preparation for a presentation will usually be stretched out over a few days. So by the time the presentation rolls around, you've been living in this world where your topic is The Most Important Thing Ever. And once it's over and the rush sort of drains out of your system, your priorities correct themselves and you realize just how insignificant your topic is in the larger scheme of things. It almost makes the presentation itself seem silly.

And yes, I know this post is completely breaking the fourth wall in ways good bloggers shouldn't. But that's because it might mess up their space suits.