OdeToCode IC Logo

Fleeting Visions Of Doom

Tuesday, April 24, 2007 by scott

Your mind is racing and your fingers are struggling to keep pace. Clickety-clackety-clickety-clackety.

New code, test code, refactored code – it pours across the screen. Clickety-clackety-clickety-clackety.

There is no passing of time in this superb condition of lucidity. Clickety- clackety-clickety-T-T-TWACK.

Opps. What was that?

Something went wrong. A finger slipped! You hit the wrong combination of keys, for sure – but which keys? Was that a menu that flashed by? The intensity of that red disk light fills you with dread. Did you trigger some hidden doomsday command that is now writing 0s to the system drive? When was the last system backup? When was your last commit? Why isn't this computer responding? What on earth is this disk drive doing? Should you cut power now and salvage what you can?

Oh, it's back <exhale>.

It's just the Visual Studio "Add New Reference" dialog.

Cancel.

For a fleeting moment, you thought all was lost.

Now, about that backup….

What's Wrong With This Code? (#14)

Tuesday, April 17, 2007 by scott

MSDN says the List.ForEach method will "perform the specified action on each element of the List".

The following program does print out a haiku to the console, but does not make the haiku all lowercase.

using System;
using System.Collections.Generic;

class WWWTC
{
    
static void Main()
    {
        
List<string> haiku = new List<string>();

        haiku.Add(
"All software changes");
        haiku.Add(
"Upon further reflection -");
        haiku.Add(
"A reference to String");

        
// make it lowercase
        haiku.ForEach(
                    
delegate(string s)
                    {
                        s = s.ToLower();
                    }
        );

        
// ... and now print it out
        haiku.ForEach(
                    
delegate(string s)
                    {
                        
Console.WriteLine(s);
                    }
        );
    }
}

 What's wrong?  

Event Validation Errors and Network Congestion in ASP.NET

Friday, April 13, 2007 by scott

Joseph Rattz emailed me about posts I wrote last year covering ASP.NET event validation (see ASP.NET Event Validation and "Invalid Callback Or Postback Argument" Part I and Part II). In the posts I describe one scenario where an event validation exception can appear, and describe how to prevent the exception. In the scenario, client side script dynamically adds values to a list (select) control. When the user POSTs the form to the server, ASP.NET sees a new value and concludes something is wrong. The list comes back to the server with a value that wasn't present when the list left the server. ASP.NET tracks the legal values by serializing them into a hidden input control with an ID of __EVENTVALIDATION. This event validation feature helps to prevent all sorts of form spoofing attacks.

Joe's scenario was odd, not only because the invalid postback argument exception appeared sporadically, but because the source of the exception was a TextBox control!

ArgumentException: Invalid postback or callback argument.  ...
  System.Web.UI.ClientScriptManager.ValidateEvent(..) ...
  System.Web.UI.Control.ValidateEvent(..) ...
  System.Web.UI.WebControls.TextBox.LoadPostData(..) ...

 

What could ASP.NET possibly validate about a TextBox? A server can expect specific values from a DropDownList, but a plain TextBox allows free form text entry by the user. The answer (via Reflector), is that the TextBox control only validates that its UniqueID is present in the legal arguments described by the __EVENTVALIDATION data. Even after knowing this information, it's hard to see what could go possibly wrong with a TextBox.

Joe's theory, which I believe to be correct, is that the user might create a postback before their browser even receives the __EVENTVALIDATION form input. This could happen, for example, over a poor connection. The resulting POST won't contain the __EVENTVALIDATION input, and thus ASP.NET cannot validate the postback arguments. The klaxons wail. Glass breaks. The runtime throws an exception.

One way to validate this theory is to simulate network congestion with the following control. We flush out the output stream, sleep, and then continue rendering.

using System;
using System.Web.UI;
using System.Threading;

namespace OTC
{
    
public class FlushAndSleep : Control
    {
        
protected override void Render(HtmlTextWriter writer)
        {
            writer.Write (
"Begin Render<br>");

            
base.Render (writer);

            Page.Response.Flush();

            
Thread.Sleep(2000);
            writer.Write(
"End Render<br>");
        }
    }
}

 

Stick the control into the following page:

<%@ Page Language="C#" %>
<%
@ Register TagPrefix="otc" Assembly="App_Code" Namespace="OTC" %>

<form id="form1" runat="server">
    <div>
        <asp:textbox runat="server" id="TextBox1" />
        <asp:button runat="server" id="Button1" text="Submit" />
        <br />        
        
<otc:FlushAndSleep runat="server" ID="FlushAndSleep" />
    </div>
</
form>

 

Run the page and click the button as soon as it appears in the browser. Voila! Instant "invalid callback or postback argument" exception! If you ever see the exception occur sporadically, this might be the reason.

DTS in SQL 2005 - Good News and Bad News

Thursday, April 12, 2007 by scott

DTS has always worried me. Unfortunately, I have 331 reasons to worry:

PS > gci -r -i *.dts | group Extension
Count   Name
----- ----         . . .
  331   .dts 

Five years ago, ADO.NET didn't have a bulkload API, and DTS seemed like the best tool for moving and transforming millions of records. This was despite the fact that the binary DTS packages check into source control as opaque blobs, and the cumbersome UI makes even simple changes difficult. We thought we'd need to write and distribute ~50 packages total, but feature growth and support for additional 3rd party databases has ballooned the original estimate.

The application using these packages has to support SQL 2000 for the foreseeable future. Not every customer has budgeted for a new SQL 2005 license, unfortunately. The good news is that SQL 2005 will run the DTS packages, even though it cannot migrate but a handful of them to the new SSIS platform.

Another piece of good news is that you can edit DTS packages in the SQL 2005 Management Studio after downloading some designer components. The bad news is that the designer is still suboptimal. For instance, the Home, End, Backspace, PageUp, and PageDown keys will quit working in the designer. The good news is that this problem is fixed in SP2. The bad news is that the fix changed the designer into a modal dialog. Modal dialogs should be banned from all software in the universe.

If you haven't started your DTS migration yet, here are a few resources I've collected.

DTS Services for SQL 2005 FAQ

SQL Server 2005 Integration Services Backward Compatibility

Known Package Migration Issues

A tool to improve DTS to SSIS migration

Any other good ones out there?

The Jesse Liberty Review

Wednesday, April 11, 2007 by scott

My publisher pinged recently to show me Jesse's review of my WF book on Amazon.com:

"Every once in a while an author is able to take a subject that others struggle with but fail to make understandable, and succeeds in making so crystal clear that it seems obvious. Allen brilliantly illuminates Windows Workflow, and his book is required reading."

I've never met Jesse, but I've enjoyed his writing over the years. Coming from an expert writer like Jesse, this comment is high praise.

What ASP.NET Developers Should Know About JavaScript

Monday, April 9, 2007 by scott

"What ASP.NET Developers Should Know About JavaScript" is the title of a presentation I'll be giving at VSLive! next month.

I don't plan for this to be a talk that features ASP.NET AJAX, or JavaScript data types. Instead, I want to focus on two key concepts I had to discover after I decided that I couldn't ignore client-scripting any longer:

  1. Every JavaScript function is an object.
  2. Every JavaScript function has an execution context.

I think these concepts are keys to understanding modern JavaScript libraries. I hope that driving home these two concepts will let a developer understand what the following code is doing, and why it works. The example is contrived, but if you can understand the following code you can follow many of the JavaScript patterns in use today.

<script src="msajax/MicrosoftAjax.debug.js"></script>
<
input type="button" value="Print!" id="button" />
<
script>

    Type.registerNamespace("Geometry");

    Geometry.Point =
function(x,y)
    {
        
this.x = x;
        
this.y = y;
                
        $addHandler($get(
"button"), 'click',
                   Function.createDelegate(
this, this.print));
    }
    
    Geometry.Point.prototype =
    {
        print:
function()
        {
            alert(
this.x + ' ' + this.y);
        }
    }
          
    Geometry.Point.registerClass(
'Geometry.Point');        
        
    
var p = new Geometry.Point(2,5);
    
</script>

There are lots of ancillary topics in the above code: object notation, prototypical inheritance, and the evils of the global object, just to name a few. However, given just 60 minutes I think that coming to grips with #1 and #2 lays a solid foundation for moving forward in the AJAX jungle.

Solutions With The VirtualPathProvider

Thursday, April 5, 2007 by scott

The VirtualPathProvider is one of the ASP.NET pieces I looked at when 2.0 was new. I suspected then that the VPP would need a little time, but would eventually be the centerpiece of some clever solutions.

Adam Kahtava has documented a number of issues he has with ASP.NET 2.0 Themes. Adam has worked around these issues by using a VirtualPathProvider. See the article descriptively entitled: "A Resolution to The Problems with Themes, Skins, and Cascading Style Sheets (CSS) - Putting the Cascades back into ASP.NET 2.0 Themes (taking control over CSS Cascades / Load Order, Media Types, and Overrides)"

Piyush Shah has devised an approach for sharing a master page across web applications by embedding the shared master page as a resource in an assembly. At run time, the VirtualPathProvider can serve up the master page from the assembly's manifest resource.

The VirtualPathProvider also works magic behind MSDN