Windows Workflow Reading List

Thursday, April 27, 2006 by scott
2 comments

Windows Workflow is a part of the next-generation APIs from Microsoft collectively known as WinFX. WinFX also includes Windows Communication Foundation and Windows Presentation Foundation. From 50,000 feet away, WinWF consists of a visual workflow designer that plugs into Visual Studio, and a runtime to execute workflow instances.

Windows Workflow from a distance

Here are some WinWF blogs I read:

Paul Andrew (technical PM)
Jon Flanders (a great collection of Biztalk and Workflow posts)
Dharma Shukla (architect)
Bayer White
Thomas Restrepro (covers a variety, including Biztalk and WinWF)
Moustafa Khalil (PM)
Dennis Pilarinos (PM)

WinWF also has a dedicated site: windowsworkflow.net, which downloads, samples, custom activities, and more.

Of course I like the following two articles:
Hello, Workflow
Authoring Workflows

If you know of some other WinWF resources, please share!

The Promise of Partial Classes and ASP.NET

Friday, April 21, 2006 by scott
4 comments

Web site projects in Visual Studio 2005 give us exactly one code-beside file per web form. We specify the name of the file with the CodeFile attribute in the form’s @ Page directive. There can be no other file – a web form and its code-beside file maintain a monogamous relationship.

But wait! Partial classes in C# and Visual Basic say I can:

“…split the definition of a class or a struct, or an interface over two or more source files. Each source file contains a section of the class definition, and all parts are combined when the application is compiled.”

True, true, but there is no capability to specify multiple files with the CodeFile attribute, and the CodeFile attribute is the only piece of information the ASP.NET runtime has available to know what else it needs to compile with the web form (each web form can compile into a distinct assembly). I can’t drop a partial class definition for the web form into App_Code, either, because App_Code compiles into a separate assembly, and partial class definitions cannot span multiple assemblies.

Let’s approach the problem from a different angle: why would we want a web form’s code-behind to span multiple files? Is the class hard to manage because it has too much code inside? That scenario sounds like an architectural problem that can’t be solved with the partial keyword. Do we want to cleanly separate event handlers from virtual overrides? Perhaps a #region would do a better job.

Web Application Projects are a different matter. WAP allows multiple partial class definitions. In fact, WAP itself will create two source code files for each web form. One file is for human generated code, and the other file is for designer generated code. This scenario is an ideal candidate for partial classes. With WAP, Visual Studio compiles all of the .cs/.vb code-behind files at once, and into a single assembly. WAP allows the compiler to merge partial class definitions.

Blame The Romans

Friday, April 21, 2006 by scott
3 comments

Blame the Romans: A Play in Two Acts
By S. Allen

Act I

[It is late in the afternoon on December 21, 2005. Two software developers, Ron and Barbara, pair program in front of a dual LCD display].

Barbara: Your fiscal year calculations are still *%#@ed!.
Ron: No, no, look. It says that March 2004 is in the fourth fiscal quarter of two thousand three. That’s right!
Barbara: I thought the finance guy said March 2004 is in the fourth fiscal quarter of two thousand and four.
Ron: Wait, when you say 2004, do you mean the fiscal year starting in 2003 and ending in 2004?

[Barbara places her index fingers on her temples, and begins to rub slowly. During these pair programming sessions, she secretly yearns to massage Ron’s temples, too. Instead of using her fingers, though, she’d prefer to use the sharp end of an Eskimo harpoon.]

Barbara: In any case, I thought they decided to display the calendar quarter, and the fiscal year.
Ron: That wouldn’t make any sense! We’ve changed this code 1000 times now! Fiscal years with calendar quarters! Fiscal quarters with calendar years! Let’s go ask the finance guys again!
Barbara: We can’t. They all left early for the office holiday party.
Ron: No! You mean we are stuck here changing this and finance is out boozing it up?
Barbara: Yep.
Ron: I’d like to meet the person who started this fiscal year thing and club him with a calculator. Do you realize how much confusion a fiscal year creates?

[Barbara still has her eyes closed, and doesn’t answer. Her mind’s eye pictures an enormous calculator falling from above, and crushing Ron’s skull. She smiles].

Ron: What are you so happy about?

[Lights fade. Curtain closes].

Act II

[It is late in the afternoon of December 21, 312 AD. Two bookkeepers, Docilus and Silius, are hunched over a table covered with wax tablets and scrolls.]

Silius: Once again, Docilus, we are finishing the yearend books while the orgies of Saturnalia rage around us.
Docilus: It is a burden we carry at the same time every year, my friend. The empire’s books must be in balance.
Silius: Indeed, but so must our spirits! My spirit is running a deficit in food, wine, and debauchery!

[Silius clears the table in front of him with a sweeping gesture, and stands.]

Silius: I have an idea, my friend!
Docilus: Do tell!
Silius: Imagine if the year didn’t end in December, but in March. Then we could also be in the streets and vomiting on the sandals of our fellow countrymen.
Docilus: This is no idea you carry in your head, my friend. It is a delusion.
Silius: No, no, Docilus. We must tally numbers for a total of 365 days, but which 365 days? I say we make a fiscal year, which runs from April to March.
Docilus: Brilliant! When do we start?
Silius: You know the old latin saying: “carpe diem”. These books can wait for 3 more months!
Docilus: Let’s party!

[Docilus rises from the table, and the two bookkeepers exit stage left. The sounds of merriment begin to echo from all directions. The abacus slips off the table leg, and breaks in two as it hits the ground.]
[Blackout.]
[Curtain falls.]

Remote Desktop Hacks

Wednesday, April 19, 2006 by scott
32 comments

I’m a heavy user of RDP (Remote Desktop, a.k.a. Terminal Services). I don’t remember how I ever got any work done before this technology existed. What follows are some miscellaneous tips.

To login to the console session on a Windows 2003 machine, start the Remote Desktop application from the command line with /console. You can also shadow a console session, so a person physically at the machine can interact with the session, too. See: How to Connect to and Shadow the Console Session with Windows Server 2003 Terminal Services. There is also an interesting but Rube Goldbergian trick I’ve never tried: How To Shadow a Remote Desktop Session in Windows XP Professional.

If you save connection settings in an .rdp file, you can add “connect to console:i:1” to make the console session preference permanent. This page extensively documents other .rdp file parameters.

When RDP misbehaves, qwinsta and rwinsta are available for remote management of sessions. Scott Forsyth has a nice write-up on how to use these tools: Managing Terminal Services Sessions Remotely.

When I connect to a Windows XP machine using RDP, the system replaces the “Turn Off Computer” button in the start menu with “Disconnect”. If I want to remotely power down the machine or reboot, I turn to the command line utility TSSHUTDN.

To connect to a Windows machine from a *nix machine I’ve used rdesktop successfully.

When paranoid, I change the default listening port for RDP on some of my machines.

Finally, some shortcut keys I commonly use:

ALT + PAGE UP replaces ALT+TAB to “tab” through running applications in the RDP window.
CTRL + ALT + + (numeric keypad plus) takes a screen print of the remote desktop (just like using PrintScrn on a local computer).
CTRL + ALT + - (numeric keypad minus) takes a screen print of the active window inside the RDP window (just like using ALT+PrintScrn on the desktop).

Any tips you want to share?

The MasterPage Article I Thought I’d Never Finish

Wednesday, April 12, 2006 by scott
150 comments

… because it kept growing and growing. I was determined to finish this off tonight before falling asleep (always dangerous).

Master Pages: Tips, Tricks, and Traps is an article covering all the inconspicuous points of developing and designing with master pages. Everything from URL rebasing, the munging of client side identifiers, using FindControl, nesting, and even tips for cross page posting.

As always, I appreciate any feedback. I’m particularly interested to know if the reader finds the intermingling of Visual Basic and C# samples to be useful, or just a terrible idea.

Now to sleep, perchance to dream...

The ContentPlaceHolder – Not Just For Content

Tuesday, April 11, 2006 by scott
7 comments

I’m working on an article full of tips and tricks for master pages. The article will be online soon, but I wanted to throw out one tip as a preview and get some feedback.  

A master page typically includes the single HTML <head> tag for a page. This approach gives every content page a <head>, but presents problems when a content page wants to add additional tags inside head, like <meta> and <link>, for example. The tags might be specific to the content page, and we wouldn’t want to include them in the .master for every page.

As long as the <head> tag has a runat=”server” attribute defined, a content page can programmatically add to <head>. The recommended ASP.NET approach to add a <link> tag, for example, is to use the following code:

HtmlLink link = new HtmlLink();
link.Href =
"~/wildStyle.css";
link.Attributes.Add(
"type", "text/css");
link.Attributes.Add(
"rel", "stylesheet");
this.Header.Controls.Add(link);

For more Header examples, see Sue’s edreams.org post.

Milan thinks the Header API is lacking functionality, and I’d agree. My frustration level rises whenever I have to modify the <head> tag programmatically, so for kicks, I tried putting a ContentPlaceHolder inside of the <head> tag:

<%@ Master Language="C#" %>
...
<head runat="server">
    ...
    <asp:ContentPlaceHolder runat="server" id="headerPlaceHolder" />
</
head>
...

Then in a web form I used a Content control to add additional scripts and metadata inside of <head>:

<%@ Page Language="C#"
        
MasterPageFile="~/Master1.master"
        
Title="Foo" %>

<asp:Content ID="Content1"
            
ContentPlaceHolderID="headerPlaceHolder"
            
runat="Server">
             
  <meta name="keywords" content="declassified information" />
  <style type="text/css" media="all">
      @import "wildstyle.css";
  
</style>
  <script type="text/javascript" src="foo.js"></script>
  
</asp:Content>

Lo and behold, this works and feels natural. No more Header.Controls.BlecktyBlah!

Except, there is a catch....

The validation engine in the Visual Studio 2005 IDE doesn’t believe a ContentPlaceHolder control belongs inside of <head>, so it raises a validation error. This is just a validation error, so the application still compiles, and still executes, but it’s an irritating validation error nonetheless, and one we can’t get rid of unless we disable all HTML validation. Ugh.

Update: The rest of this post was a late night ramble full of rubbish that didn't produce the intended result.

Move along now, nothing to see here.

To appease the deities of validation, I can resort to a hack. I can move the master's ContentPlaceHolder for <head> related goo inside of the <form> tag. This avoids validation error flags, and feels justifiable because all the webforms look more maintainable. The master page only needs to swap the ContentPlaceHolder into the Header controls collection during the page lifecycle.

In other words, with a master page like this:

<%@ Master Language="C#" %>

...
<head runat
="server">
    <title>Untitled Page</title>
    
</head
>
...
    <form id="form1" runat
="server">
     <asp:ContentPlaceHolder runat="server" id="headerPlaceHolder"
/>
     ...
    </form
>
...

All we need is some code behind the master page, or in a master page base class like so:

protected void Page_Init(object sender, EventArgs e)
{
  Controls.Remove(headerPlaceHolder);
  Page.Header.Controls.Add(headerPlaceHolder);
}

The .aspx webforms can add to <head> declaratively, using a Content control.

What do you think? Good? Bad? Dirty?

Ultra-Mobile Pricey Computer

Thursday, April 6, 2006 by scott
0 comments

When news of Project Origami began to spread like avian bird flu, I thought the decision to buy an ultra-mobile PC would be a no-brainer. A small device that can run Word, Outlook, OneNote, and GPS software on a reasonably sized display sounds infinitely useful - all I would need is a fashionable man purse to carry my computer around, right casey?

Now I’ve seen some specs and reviews come on-line.

Dr. Neil is playing with a pre-production UMPC and reports the battery life as ‘just over two hours’. I was hoping for 4.

Meanwhile, the Samsung Q1 is available for preorder in the UK at a price of £800 (almost $1400!). The TabletKiosk eo is also available for pre-order at a price of $900. The troubling fact is $900 only buys 256MB of RAM and a 30GB drive, which is what I expected for $600 entry-level units.

I have not spotted any prices for the unit I’m most interested in, the Asus R2H. The Asus model is rumored to ship with a GPS receiver, fingerprint scanner, and camera. Given the early pricing on other models, I won’t be surprised to see the Asus come in over $1600. At that price point one has to think about the tradeoffs between a UMPC versus a slate or convertible tablet.

Jumping on the first generation UMPCs isn’t the easy decision I first thought. Still, the voice on my shoulder tells me the UMPC could be a lot of fun to develop for…

by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!
(c) OdeToCode LLC 2004 - 2014