October 2005 - Posts

Scary Software

In honor of Halloween, I was trying to think of the scariest software I’ve ever met.

A long time ago, I worked on an embedded project building one of those blood pressure kiosks like you'll find in a drugstore. The brain of the machine was a little 8 bit CPU. Every so often, I’d volunteer my own arm in the machine and measure my blood pressure as a test.

You know when you are getting your blood pressure measured in the doctor’s office …
… and the rubber bladder is starting to feel extra snug around your arm ...
… and you are wondering if the person who is pumping air into the bladder will stop soon?

Now imagine – instead of a person pumping air, there is a machine filling the bladder …
… using software written in C …
… where it only takes one NULL pointer to really make for a spectacular crash.

Scary thoughts were often in my head when my arm was in the machine. I hated it, although nothing bad ever happened.

Eventually, the FBI came, and I retired from embedded work.

posted by scott with 2 Comments

Medium Trust ASP.NET Applications

If you are an ISP offering shared hosting, or you are a developer deploying your app in a shared hosting environment, then there is no doubt you want to avoid running ASP.NET applications with full trust. Full trust is the default trust level for ASP.NET.

What is full trust? The runtime defines several trust levels we can use to constrain what an application can do. These trust level range from minimal trust, which is a highly restrictive level, to full trust, which has no restrictions at all. The recommended trust level for an ASP.NET application is right in the middle: medium trust (see the ASP.NET 2.0 Hosting Deployment Guide).

What is wrong with full trust? For starters, the AppDomain hosting the application is no longer a security boundary. Full trust allows native code to execute, and native code can poke around a process that is hosting multiple AppDomains to find or corrupt data from other applications. Full trust also leaves resource protection up to the operating system, which is a bad idea when all the applications are running with the same identity, and thus have equal access to files and registry keys.

For instance…

    1 string parentPath = Server.MapPath("~") + @"\..\";

    2 

    3 string[] webDirectories;

    4 webDirectories = Directory.GetDirectories(parentPath);

    5 

    6 foreach (string directory in webDirectories)

    7 {           

    8     string appDataPath = directory + @"\App_Data\";

    9 

   10     string[] appDataFiles;

   11     appDataFiles = Directory.GetFiles(appDataPath);

   12 

   13     foreach (string file in appDataFiles)

   14     {

   15         try

   16         {

   17             // goodbye, data

   18             File.Delete(file);

   19         }

   20         catch(Exception)

   21         {

   22             // eat it and go on

   23         }

   24     }           

   25 }

The above code tries to walk through the web sites on a server and destroy any files in the well known App_Data directories. Perhaps a database file will be in use and the runtime will throw an exception – that’s ok, we can try again later. The real problem here is that the code can even successfully retrieve a listing of files and directories outside of the root where the code executes.

Medium trust will place a number of restrictions on an application, including limiting an application’s file access to within the virtual directory where the application lives. If we run the above code under medium trust (see How To: Use Medium Trust in ASP.NET 2.0), the runtime will throw a System.Security.SecurityException exception on line 4. Line 4 is the where the code tries to get a list of directories one level above the application’s home directory.

In ASP.NET 2.0, Microsoft has made changes to make life easier for ISPs and developers who want to run code with the medium trust level. You can read more in the PAG document: Security Guidelines for ASP.NET 2.0.

posted by scott with 11 Comments

New Microsoft Certifications

The curtain is rising on a new set of Microsoft certifications. I’m particularly interested to see how the new exams fare, as I’ve contributed some blood, some sweat, and quite a few tears in contributing content to these exams, as have many others.

The value of a certification is a hotly debated topic. I think you have to examine the subject from two perspectives.

From a personal perspective, I believe the value of a certification is what you make of it. When I studied for my MCSD years ago, I spent time looking at the objectives, then reading books, looking at examples, and most importantly: writing code. When my certificate arrived, I felt I had truly earned something of significance.

Contrast this experience with people I know who work for large consulting firms. Big consulting firms like developers with certifications because they can bill the dev out at a higher hourly rate. The firms will happily send a dev to a one week crash course with a Friday afternoon exam. If the dev already has the skills, you could say this might not be a bad idea, but I’m sure for many people in that scenario, all they earn are pieces of paper with colored ink.

Then there is the other side of the coin. What value do you apply to a certification when you are looking at job candidates? I’d never hire a person just because they have a cert, and I’d never give a thumbs down to someone because they didn’t have a cert. The trick in small companies is to hire people who are passionate about their chosen profession, certification or not.

In any case, software certifications need to continually evolve, improve, and refine themselves, just as software development does. I hope the industry perceives this set of exams as raising the bar – I’ll feel proud.

posted by scott with 4 Comments

Debugging With Visual Studio

A basic introduction of the debugger features for those new to the F5 key.

The debugger in Visual Studio 2005 is an amazing piece of software. You can debug C# and C++, Visual Basic and VBScript. Step over managed code, native code, mobile code, and T-SQL code. You can debug locally, or you can debug remotely. You can debug assemblies hosted by SQL Server, and JavaScript hosted by Internet Explorer. There is just-in-time debugging and Just My Code debugging. You can step into XML web services and into XSL transformations. The debugger has data tips, and data visualizers, breakpoints and tracepoints. You can inspect threads, modules, memory, and call stacks; you can view both local and global variables.

If you have a bug you can’t track down with Visual Studio, you’ve got yourself a real sticky problem.

Read more...

posted by scott with 32 Comments

Thanks

Thanks to everyone who came to my debugging presentation at VSLive! in Orlando. I received some nice compliments afterwards that mean a lot to me.

Thanks to Scott C. Reynolds for hanging at the exhibition dinner.

Thanks to Sam Gentile and Robert Hurlbut for letting me tag along to the seafood dinner on Wednesday. Robert will be coming to the MAD Code Camp in a few weeks. Sam will be coming to my area in December to speak at the CMAP user group. Sam was recently elevated to the status of Architect MVP, so I expect him to trade in his Rotor and IL slides for clouds and class diagrams.

Finally, thanks to Ken the van driver who took me back to the airport. Ken was the most entertaining and informative driver I’ve had the pleasure of meeting. Have fun on your vacation and upcoming retirement, Ken.

posted by scott with 3 Comments

Debugging XSLT

Hidden in the numerous debugging features of Visual Studio 2005 is an XSLT debugger.

Open an XSLT file in the IDE and the XML menu and toolbar will both appear with “Debug XSLT” options. Selecting debug will prompt you for an XML file to transform. The output appears in real time.

What is amazing about the debugger is the number of classic debugger features that “just work”. You can set break points, step in, step over, and run to cursor. The locals and watch windows work, as does the call stack window (you can see which apply-templates brought you to the current location). Another goodie: the immediate window lets you type in XPATH expressions for evaluation in the current context.

Wait, there’s more!

2005 can also step into the Transform method of an XslCompiledTransform instance. Just enable debugging by passing a true as the first parameter for the XslCompiledTransform constructor. Be sure to read the remarks section of the documentation because some restrictions apply. In one scenario I can consistently crash the release candidate build of 2005.

posted by scott with 1 Comments

Bit Flipping the Binary Search Result

When I did the Atlas hands on lab weeks ago, the following piece of code jumped out at me:

int index = Array.BinarySearch(

       autoCompleteWordList,

       prefixText,

       new CaseInsensitiveComparer()

   );

 

if (index < 0)

{

    index = ~index;

}

Why is the code doing a bitwise complement (~) on the return value of BinarySearch?

My next stop was the documentation for the return value of Array.BinarySearch, which states:

The index of the specified value in the specified array, if value is found. If value is not found and value is less than one or more elements in array, a negative number which is the bitwise complement of the index of the first element that is larger than value

In other words, if you don’t find an exact match you can flip all the bits and have an index pointing to something close – a good trick to know when building an auto-complete control.

posted by scott with 5 Comments

Using MSBuild and ILMerge to Package User Controls For Reuse

One of the advantages to ASP.NET server controls is the ability to package them into an assembly and reference them from other web applications. Server controls are relatively difficult to write but easy to reuse. User controls (ascx files), on the other hand, are relatively easy to develop, but don't like to swing with other projects. A common solution in 1.x involves setting up virtual directories. Yuck.

The ASP.NET 2.0 environment is different. We have MSBuild. We have an ASP.NET compiler. Perhaps you've also noticed we have a tool by the name of ILMerge.

Here is a proof of concept.

Step 1: I created a new solution in Visual Studio 2005 and added a plain class library project. I then added two user controls to the project, which Visual Studio doesn’t like initially, but it does all work, even the intellisense. The first user control is all inline code:

<%@ Control Language="C#" ClassName="SayHello" >

<script runat="server">
  <protected void Page_Load(object sender, EventArgs e)
  {
    label.Text = "Hello at " DateTime.Now.ToShortTimeString();
  }       
</script>

<asp:Label runat="server" ID="label"/>

The second control, SayGoodbye.ascx, is the same, except it puts the Page_Load logic into a separate CodeFile by the name of SayGoodbye.cs.

Step 2: One of the cool features of Visual Studio 2005 is that the project files are MSBuild files. The default .csproj file for the class library I created does not know what to do with .ascx user control files, but I help it. I can right-click the project and select unload, then right-click the now disabled project and select Edit. Behold - the project is exposed naked before me. Pure angle-brackety goodness.

What I want to do at this point is modify the project to run the ASP.NET precompilation task – easy enough since there is an MSBuild task available by the name of AspNetCompiler. What is tricky is that AspNetCompiler will likely produce multiple assemblies. The compilation tool will batch compile by default, which means one assembly per directory of user control files. Of course we don’t want to keep all the ascx files in the root of the project, and we don't want to reference an entire directory of .dll files, so this is where ILMerge comes in.

ILMerge is a utility to merge multiple .NET assemblies into a single assembly. Combining AspNetCompiler and ILMerge together gives us something like the following:

<Project DefaultTargets="CompileUserControls" 
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
           ...
  <Target Name="CompileUserControls">
    <!-- TargetPath cannot be underneath PhysicalPath :( -->
    <AspNetCompiler 
      Debug="false"
      PhysicalPath="$(MSBuildProjectDirectory)" 
      TargetPath="$(TempDirectory)" 
      Updateable="false" 
      Force="true" 
      VirtualPath="$(MSBuildProjectName)" />

    <CreateItem Include="$(TempDirectory)\bin\*.dll">
      <Output ItemName="PrecompiledAssemblies" TaskParameter="Include" />
    </CreateItem>
    
    <Exec Command="$(ILMergeEXE) /out:$(MSBuildProjectName).dll 
                    /targetplatform:v2 @(PrecompiledAssemblies, ' ')" />
  </Target>
    ...

Inside the target I first run the AspNetCompiler and produce all the user control assemblies. Next, I need a list of all the assemblies the compiler just spit out. I do this with , which produces the Item PrecompiledAssemblies (thanks to Chris Tavares and the Chris Sells' Win-OT list for figuring this out). The last piece is to execute the ILMerge tool, passing all the assembly names as command line arguments.

Plop! Out comes ReusableControls.dll.

For the last step, I created a new web project and referenced ReusableControls.dll, then created a little test aspx web form.

<%@ Page Language="C#" %>
<%@ Register TagPrefix="rc" Namespace="ASP" Assembly="ReusableControls" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<form id="form1" runat="server">
   <rc:SayHello runat="server" ID="hello" />
  
   <br />
  
   <rc:saygoodbye_ascx runat="server" ID="goodbye" />
  <br />
</form>

Notice in the @ Register directive we need to specify a namespace of ASP, as this is the default given by the AspNetCompiler. The compiler also munges the user control name when a CodeFile is used – we are using the class that was code-generated from the SayGoodbye.ascx file and inherits from the SayGoodbye class in the CodeFile. With inline code there is no adjustment.

It might be possible to also re-use master pages and webforms with a little bit of VirtualPathProvider trickery, but I’m not going there as yet. I want to see how this will shake out at RTM time when combined with the Build Project that should arrive, as announced by others.

posted by scott with 32 Comments

Page_Load versus OnLoad

ASP.NET developers typically handle a Page object’s Load event with a Page_Load event handler. In 1.x the designer generates code inside an InitializeComponent method to explicitly wire Page_Load to the Load event.

Lately, I’ve seen more than a handful of people dropping the Page_Load event handler in favor of overriding the Page OnLoad method. This appears to be happening more and more in 2.0, for a few reasons.

First, for C# developers using a separate CodeFile, it’s not immediately obvious how to add any Page event handler if the event is not already present. Unlike the VB editor, there are no drop down controls available to add an event, and intellisense offers no assistance. The method signature has to exactly match what ASP.NET will be looking for, because C# webforms use AutoEventWireup=”true”. Ironically, VB webforms use AutoEventWireup=”False” because the Handles keyword allows a VB developer to wire up an event in place.

Secondly, there is a small performance benefit in not creating a delegate (with reflection no less) and having the garbage collector clean up the same delegate afterwards.

I’ve been thinking about the OnLoad approach, and I even posted code in a recent entry using OnLoad instead of Page_Load. I’m not comfortable enough to make the switch, however. The purpose of OnLoad is to raise a Load event. Overriding a virtual method implies I want to change that behavior, which isn’t precisely true – I just want to setup the webform and get ready for databinding, etc. There is also a comfortable consistency in handling all Page and control events using event handlers of the form VariableName_EventName. Finally, if someone forgets to forward the OnLoad call to the base class, frameworks will break easily.

Opinions?

P.S. To add Page event handlers in C# code easily, use inline code instead of a separate code file. The ASPX editor provides the drop down controls to select Page events when in source view. Drag and drop, baby. It’s the future.

posted by scott with 16 Comments

If All Movies Ever Made Were Really About Software...

A Few Good Objects
Col. Jessup: You want destructors?
Kaffe: I think I’m entitled.
Col. Jessup: You want destructors?
Kaffe: I want deterministic finalization.
Col Jessup: You can’t handle deterministic finalization!

Pulp Compilers
Vincent: You know what they call a switch statement in VB?
Jules: They don’t call it a switch statement?
Vincent: No man, this is the same language that has an AndAlso operator.
Jules: Then what do they call it?
Vincent: They call it a Select Case.

Full Metal Packet
Gunnery Sargent Hartman: My orders are to weed out all non-hackers who do not pack the chops to serve on my beloved accounting package software project. Do you maggots understand that?

Star Warez
[R2-D2 and Chewbacca are pair programming aboard the Millennium Falcon]
Chewbacca: Wurgleaaaaaaaghooooo!
C-3PO: It’s legal syntax. Screaming about it won’t help you.
Han Solo: Delete it. It’s not wise to upset a wookie.
C-3PO: But sir, nobody worries about upsetting a droid.
Han Solo: That’s because droids don’t pull people’s arms out of their sockets over bad code. Wookies are known to do that.
Chewbacca: Rrrrroo.
C-3PO: I see your point, sir. I suggest a new strategy , R2. Let the wookie take the keyboard.


Lord Of The Token Rings
Aragorn: Are you frightened?
Frodo: Yes.
Aragorn: Not nearly frightened enough. I know your bug count.

Null Terminator 2
Terminator: I need your source code, your compiler, and your static code analysis tools.
Biker: You forgot to say please…

Bridge Pattern Over The River Kwai
Colnel Saito: Do not speak to me of rules! This is software programming! This is not a game of cricket!

2001: The Speech Recognition Odyssey
Dave: Open the pod bay doors, HAL.
HAL: What did you say about Bombay, Dave?
Dave: I said open the pod bay doors, HAL.
HAL: I don’t know anyone named Doris, Dave.
Dave: Give me a freakin’ keyboard!

posted by scott with 2 Comments

MVP Summit Pictures

Here is a sampling of pictures I took during the summit.

This first photo is from Wednesday night’s dinner. Roughly 35% of the seats at my table were filled by a Scott. In this photo, Scott Hanselman is comparing mobile devices as Scott Bellware and Milan Negovan look on. Scott H does a great Jimmy Stewart.

Also at the table was Bill Vaughn. Bill and I suspect we are long lost cousins – we both descend from Allen families of the Shenandoah Valley.

Here is a shot of Bill Ryan, Sahil Malik, and Jonathan Cogley. Sahil is presenting at the local user group this Tuesday – come on out and ask him why he prefers a Motel 6 to the W. Whatever, Sahil.

This is a picture of my favorite bus driver: Ted. Ted is what I call an optimistic driver. When Ted would see cars stopped 100 feet ahead on the freeway, Ted wouldn’t slow down a bit. Ted believed the cars would be moving again by the time we arrived at their bumper. We often decelerated from cruising speed to a dead stop in 3 milliseconds. In spite of passengers screaming “Ouch, my spleen!”, Ted remained very optimistic.

I have pictures of G. Andrew Duthie on a Karaoke stage, but Paul Glavich has done one better and posted video. We need a Karaoke machine at the next code camp.

This last photo is Darrell Norton at the airport. Darrell, in true agile form, was demonstrating user stories in preparation for project “Getting Some Sleep On A Redeye Flight”.

posted by scott with 7 Comments

ASP.NET 2.0 User Controls in App_Code

Here is a tip I picked up at the MVP summit from ASP.NET team member Simon Calvert.

You can place a user control file in App_Code, as long as the .ascx uses inline code. The user control will compile into the App_Code assembly. Instead of using LoadControl with a virtual path parameter, you can use the overloaded version accepting a Type parameter.

As an example, here is the contents of MyUserControl.ascx. Place the file in the App_Code directory.

<%@ Control Language="C#" ClassName="MyUserControl" %>

 

<script runat="server">

 

  protected override void OnLoad(EventArgs e)

  {

    base.OnLoad(e);

    Label.Text = "Bonjour!";

  }   

 

</script>

<asp:Label runat="server" ID="Label" />

Here is the code for a web form that dynamically loads the control.

using System;

using ASP;

 

public partial class _Default : System.Web.UI.Page

{

    protected override void OnInit(EventArgs e)

    {

        base.OnInit(e);

 

        MyUserControl c;

        c = LoadControl(typeof(MyUserControl), null)

            as MyUserControl;

 

        if (c != null)

        {

            Controls.Add(c);

        }

    }

}

Note: No @ Reference directive was required in the .aspx file.

Why is this interesting?

I was conversing with Shawn Wildermuth, and Shawn is unhappy with the solutions needed to make types visible in the ASP.NET 2.0 compilation model, solutions like using @ Reference and stubs. Shawn is not the only one. The above solution is easy if you don’t mind using the App_Code directory. The user control type will be visible to both the App_Code assembly and all web form assemblies.

posted by scott with 13 Comments