Monday, July 30, 2007

Finding an Active Directory User by Their Security Identitfier (SID)

Problem: You need to store a unique identifier for a Windows user in your application database that is not subject to change. Their NT Login Name is potentially volatile, so you choose to store the NT Security Identifier, the SID. You need to look up certain details per user in the Directory when the user logs into your application, rather than storing duplicate data in your membership table(s). Since you are only storing the SID, you must perform this lookup by obtaining the SID of the authenticated principal and looking it up in your membership table(s).



Sounds fairly straightforward, until you discover and/or realize that security identifiers for Active Directory user objects are not stored using the Security Descriptor Definition Language format (i.e. SecurityIdentifier.ToString(), e.g. "S-1-5-9-..."). The SID of a Windows principal is stored as a binary value in the directory. Constructing a LDAP filter to find the appropriate user's directory entry means understanding:


  • how the LDAP specification represents binary values as strings,

  • which property of a user directory entry contains the Windows SID

  • how to obtain the binary representation of SID from a SecurityIdentifier object

  • how to apply string formatting codes to a byte value in order to obtain a hex string




Fortunately, dear reader, I have done all the leg work on this one. This article is a continuation of a loosely-coupled series of articles giving you the know-how required, without specifying exactly how, to build a dual-mode authentication (Windows/Forms Auth) membership architecture for your ASP.NET applications.



First off, the RFC says that LDAP formats binary value in filter strings by delimiting each byte with a backslash ("\") character and writing the hexadecimal value of the byte. So, we need to:


  1. obtain the binary value of the SID

  2. convert each byte to this string format

  3. append it to our LDAP filter



//(1) assuming a SecurityIdentifer sid;
byte[] sidBytes = new byte[sid.BinaryLength];
sid.GetBinaryForm(sidBytes, 0);

//(2) assuming a StringBuilder sb;
foreach(byte b in sidBytes)
{
sb.Append(@"\");
//formats a byte using a two-digit hex value representation
sb.Append(b.ToString("X2"));
}

//(3) to be used in an LDAP query
String.Format("(&(objectClass="user")(objectSid="{0}"))", sb.ToString());



I hope this helps!

Wednesday, July 25, 2007

A PowerShell Script to Determine Directory Size

Here's a script I wrote to determine the size (in megabytes) of all the files in a directory and its subdirectories. This should be a bit more accurate, if less precise, than what you get in Windows Explorer.




function GetSize()
{
$size= gci -recurse -force |
? { $_.GetType() -like 'System.IO.DirectoryInfo'} |
% {$_.GetFiles() } |
Measure-Object -Property Length -Sum |
Measure-Object -Property Sum -Sum

$size2 = (Get-item .).GetFiles() |
Measure-Object -Property Length -Sum

[System.Math]::Round(($size.Sum + $size2.Sum) /
(1024 * 1024)).ToString() + "MB"
}

Friday, July 20, 2007

Aspect-Oriented... JavaScript?

Or, how to create an event handler where there wasn't one.


Some background: I wanted to open a window (a RadWindow actually from the Telerik RadAjaxManager) and refresh a portion of the screen (a RadAjaxPanel) when the window was closed. Unfortunately, the developer of the window library (Telerik) didn't anticipate this by creating an OnClose property of the window class. In fact, they had not event handlers at all in the client-side JavaScript object model for the window.


So, what to do? How can I know when the window is closed? Well, a procedural programmer might simply poll the window handle periodically until the window is closed. An object-oriented programmer would decry the lack of an observer pattern in the 3rd-party's object model, and fall back to wrapping the procedural approach in a bunch of classes. What about the functional programmer? The answer looks something like this:


whenReturning(getWindow(),'Close', refreshScreen);


In the code above, getWindow returns a window object reference, 'Close' is the method called to close a window, and refreshScreen is a function object that we want to call when the close method returns. Take a moment to drink that in... What this code describes is a standard way to create your own event handler. In plain English, what the code above does (I'll show you how in a moment) can be stated as, "whenReturning from the getWindow().Close method, refreshScreen". That's powerful.


The semantics are different from wiring up event handlers; we're not making an assignment to an "OnXXXX" property of the object. In the .NET parlance, we're not making a "type safe assignment of a delegate instance to a multicast delegate". To a functional programmer, this semantic is more natural. To folks acquainted with aspect-oriented programming, this may also seem familiar. The function "whenReturning" is providing advice ("refreshScreen") at a join-point ("getWindow().Close"). In fact, this is the perspective of the article where I first picked up this technique.


In a blog entry "Aspects in JavaScript", William Taysom describes how to implement AOP advice using some of the features of JavaScript, including closures, type mutability, and dynamic scoping. (He's a fan of dynamic languages.) The article assumes a lot of context and understanding on the part of the reader regarding these language features.



If you're looking for a quick solution, you might have better luck using dojo.event.connect. Here's a snippet from their site, "[...] lets say that I want exampleObj.bar() to get called whenever exampleObj.foo() is called. We can set this up the same way that we do with DOM events:"


dojo.event.connect(exampleObj, "foo", exampleObj, "bar");


So, if you need a quick win here, go grab dojo and use their event connector. If you're new to JavaScript as a dynamic, functional language, you would do well to learn about how functions are first-class objects, all of an object's properties are an index into a dynamic associative array, inheritance through prototypes, and how lexical scoping works with "this" and closures. At the very least, to understand the code in the "Aspects in JavaScript" article, you need to understand function call dispatching in JavaScript.


Building off of William Taysom's work, we could extend this advice to all instances of the window (RadWindow) object by modifying the prototype. That may be the subject of a future post. Until then, dear reader, best wishes.

Befuddling Error: "The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases."

If you ever modify the controls collection (e.g. myControl.Controls.Add()) of a parent control, such as the Page, inside a UserControl you my have seen the following error.

"The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases."



Unfortunately, this error is a bit obtuse, since we can most certainly modify the controls collection in event handlers that take place during those phases. So, what should we divine from this error message? It helps to remember this error is being thrown by the control collection that the current control is contained in, or another level up in the controls collections hierarchy.



My understanding is that you can modify down, not up, in the controls hierarchy. In other words, if you want to add a control dynamically to your parent, the parent needs to have a place to put it. The solution is to add a PlaceHolder control to the parent, then add your controls dynamically to that PlaceHolder.

Wednesday, July 11, 2007

An IE OnChange Textbox AutoPostback Twice RadAjaxManager Workaround!

I cannot personally justify the difficulty of finding this workaround, but I know someone will find it valuable. An ASP.NET box with AutoPostback="true" on my page was causing an ajax postback twice through the RadAjaxManager, and it took me a long time to figure out why. So, I post my findings here in the hope that Google will help another frustrated developer find the solution they need.



First, a description of the difficulty I was having in my ASP.NET application. I'd created several textbox controls that I wanted to have AutoPostback. Then, using the RadAjaxManager, I wanted to have the textbox controls perform their postback using an ajax request and update another portion of the screen where the results of the request would be displayed. When the request completed, I wanted the textbox control that caused the postback to have an empty value.



So, I set the AutoPostback property of the textboxes to True, created AjaxSettings to have the results panel and the search panel (where the textboxes live) update when one of the textboxes caused a postback. I entered some text into one of the ajaxified textboxes, hit ENTER, then, voilà, it performed an ajax postback updating the panels I specified...



Then, it did it again.



The ajax postback was performed twice. Every time. Great... So, I set about to determine why this was occurring. Along the way I discovered a few things about Internet Explorer, the ASP.NET JavaScript postback model, and how the Telerik RadAjaxManager works with them.



If you created a little test page that fires an alert in a textbox's onchange event, you'll notice a difference in behavior between IE and Firefox. For example, put this element into an otherwise blank page.


<input type="text" onchange="alert('fired');" />

In Firefox, entering some text and pressing the ENTER key will result in the alert being shown; in IE, however, this is not the case. IE doesn't fire the onchange event until the textbox loses focus.



This creates a browser incompatibility issue for libraries. Pertinently, consider setting the AutoPostback property of an ASP.NET textbox to true; when the textbox is changed in the browser, the client should perform a postback automatically. Obviously, the ASP.NET developer's must have worked around this behavioral discrepancy. Indeed they did:


<input type="text"
onkeypress="if (WebForm_TextBoxKeyHandler(event) == false) return false;"
onchange="javascript:setTimeout('__doPostBack(\'textbox1\',\'\')', 0)"
... />
Please note that some rendered properties of the textbox have been elided for clarity.

What is this WebForm_TextBoxKeyHandler? Some clever use of our Javascript debugging tools reveals the answer: it fires the onchange event for the textbox when the ENTER key is pressed and returns false.



That the WebForm_TextBoxKeyHandler returns false when the ENTER key is pressed (after firing onchange event handler) is significant. It means that the browser will cancel the keypress event. Thus, Firefox will not trigger the change event for the textbox.



We now have a few clues to the mystery of why our page performs the postback twice when we change our textbox:


  1. When we hit the ENTER key in both browsers, the onkeypress event handler executes the onchange handler. We changed this behavior.

  2. When we navigate out of the textbox, the change event is fired. This behavior remains unchanged.


Please note the added emphasis in the above two items. The ENTER key causes the onchange handler to be executed, while navigating out of the textbox causes the change event to be fired which executes the onchange event handler. I am not making a semantic distinction here; these are two entirely different behaviors.



Notice there isn't a problem so far, however. No matter how the onchange event handler gets called, it calls __dopostback which is going to cause our page to go away. The problem only presents itself when the page doesn't go away: when we peform AJAX postbacks.



With an AJAX postback (i.e. after we wire up the controls using the RadAjaxManager), the textbox that caused the postback stays in the page, and when we navigate out of it the change event is going to be fired. Here's what's happening:


  1. Navigate into textbox--current value is stored as original value.

  2. Enter text and press ENTER.

  3. onchange event handler is executed (via the onkeypress event handler)

  4. AJAX postback occurs

  5. navigate out textbox (e.g. loading screen displayed or user-initiated)

  6. change event is triggered

  7. onchange event handler is executed by change event

  8. AJAX postback occurs




The two postbacks can seem to occur concurrently in Firefox if you cause the textbox to lose focus when performing the postback, e.g. if you displayed the loading panel over it. The postbacks always occur serially in IE in the same situation; because, although the requests are both queued up by simultaneously by the scripting engine just as in Firefox, AJAX in IE relies on the a single-threaded COM component (XMLHttpRequest) to communicate with the server. So, IE can only execute one AJAX request at a time in this situation.



We have a problem here, gentle reader. We do not own any of the code in the scenario enumerated. How should we go about creating a solution, then? One's first instinct might be to clear the textbox in the onblur event handler. Unfortunately, browser divergences strike again. Whereas Firefox fires the user-supplied onblur event handler before checking if the textbox has changed, IE checks the change first.



What about clearing the textbox in the onchange event handler? This would only work if:


  1. we could ensure that the textbox would not lose focus before our code was run, and

  2. we clear the textbox only after all other onchange code has run to ensure that we actually send a value!


Thankfully, there is a solution.



The RadAjaxManager supplies a set of ClientEvents that we can use to get some of our code executed in the midst of its ajax postback. We will utilize the OnRequestSent client event of the manager to clear the value of the textbox. In the function assigned to the OnRequestSent event, we place the following code:


args.EventTargetElement.value = "";



Keep in mind that this event gets fired for every ajaxified control associated with your RadAjaxManager, so you may find it necessary to qualify the aforementioned line of code to only clear the appropriate textbox controls.



I sincerely hope this helps others.

Friday, July 6, 2007

Some Cool Web 2.0 Applications

Our first is related to the still-born Snap.com. It's called WebSnapr, and I'm going to try it here on the blog for a while. Preview thumbnails of pages that I link to will show up inside of this preview bubble:




Second, we have the Y-Combinator funded Snipshot. This is a primitive image editing program that runs completely in the web browser.



Lastly, and perhaps the most impressive to readers of this blog, I want to mention Yahoo Pipes.

Thursday, July 5, 2007

Do You Hear a Bell Tolling?

“No man is an island, entire of itself ... Any man's death diminishes me, because I am involved in mankind. And therefore, never send to know for whom the bell tolls; it tolls for thee.”

—John Donne from "For Whom the Bell Tolls"


Has Microsoft died? Should I be concerned that your career might go with it? Its savior is long quiet; Ozzie last posted about Live Clipboard in April of 2006. I first expressed my concern publicly four months later, but I recently heard new development is going away from .NET and toward dynamic languages, at least for ThoughtWorks.



Microsoft made huge gains in the server market in the first part of the 2000s. .NET was to be their coup de grâce; and it worked for a while.



That is until the innovation in the web-space picked up again. It no longer pays to be average. So, besides serving as a brain-backup device for various solutions I've hammered out, this blog will also be the place where I try to incorporate what I learn from these high-falutin' technologies into my work as a C# programmer.



And, who knows? Maybe I'll learn a new language and escape the cave. If so, despite Plato's warnings, I will return to share what I've seen. Until then, however, I will continue to be impressed by Windows Workflow Foundation

Wednesday, July 4, 2007

More on Closures

In yet another simple and highly illustrative example of why closures matter, here's a blog entry representing asynchronous (non-blocking) network I/O with closures. Note the significant reduction in code needed and elimination of explicit state management.




I've reproduced the author's closure-enabled Python code in C#:




The above code doesn't exactly mirror the original author's intent; we could easily utilize an AsyncCallback to to that. What it does do is clearly illustrate how to anonymous methods are used to create lexical closures. In "DoOperationB", we see that after it returns its local "stage2" keeps a reference to another local, "stage3".



The order of execution will be what we intended: DoOperationB, stage2, stage3; however, all of this happens in a non-blocking manner. We could call DoOperationB several times, and upon each execution a new lexical scope would be created that the respective "stage2" and "stage3" delegates would act upon. Without real-world code it may be difficult to see, but the benefits of this approach include:


  • not having to utilize callbacks, and

  • not having to bookmark/track execution state, and (perhaps most subtly)

  • the entire "operation" is modeled in exactly one named method (DoOperationB).

Hello?



Can you hear me now? Has anyone ever been able to actually have a live chat using one of these sites?

When did customer service become so hard?

Monday, July 2, 2007

Replace enum Constructs with Classes

Anyone who knows me, knows I'm perfectly happy writing C# code. But I think its important to keep tabs on what the rest of the industry is doing, especially things that come out of the Java space. Witness the omniscient debugger, Guice, and db4o. Along those lines, I've read a bit from a book entitled Effective Java, written by Joshua Bloch, and I'm happy to report that it has made me a better programmer. My favorite gem, so far, is something that I attempted to do about five years ago--replace enums with classes.



First, some background on my initial motivation. What I kept running into were string values that corresponded to various codes that would be kept in the database. You know what I mean, you've got addresses and address types (e.g. home & work, or mailing & billing, etc.). So, you store a string that indicates what type of address it is and expose that as a property of your address object. The problem is a distinct code smell that something is wrong:



if (addr.AddressType == "M")


Of course, this looks like a magic number, so to speak... and comes with all the attendant difficulties in maintainability of the code: what is "M", what does "M" mean, what happens when we phase out "M"? We could probably make an accurate guess given something as prosaic as addresses, but what about exception policies or authentication modes?



What I wanted at the time was a "typesafe string enum". Put in more concrete terms, I wanted to do the following:


if(addr.AddressType == AddressTypes.Billing)


Now, Java doesn't have built-in enum support, whereas .NET does support named integral enumerations as a first-class type. So, we could implement the above with the following declaration:



public enum AddressTypes
{
Mailing,
Billing,
Residence
}

This would work fine, except that we need some fixed mechanism for identifying address types outside of our code (i.e. in the database or in an XML wire-serialization). So, we simply explicitly identify these constants:





Okay, we're golden! Or, are we? Let's look at this design choice in practice. Consider what a customer address record might look like:



CustomerID AddressType AddressLine1 AddressLine2 ...
243843 2 1032 North St. NULL

Hmmm, that's not so bad. We could use a lookup table and a view to make reporting and querying easier. What about XML serialization of a customer object:




Still, that's not terrible, but it could be better. There's a very good reason why XML is human-readable. It makes consuming data easier for systems outside of the system where the data was originated. That is, when the marketing department hires someone to come in and integrate their CRM system with your customer database, they have to figure out that "2" means "Billing".



There's that magic number again! What we have implicitly done with the enum serialization is leaked an implementation detail, e.g. how we represent Billing addresses in our system. We have violated the encapsulation principle. Cue the warning music (dum-dum DUM)!



It's not just other systems that will have some difficulty with these magic numbers. Consider how you would store a default address type in a configuration file, for example defaultAddressType=2.



There are other difficulties with enums. Probably the most pertinent is related to how enums are implemented. Specifically, an integral value is implicitly convertible to an enum instance. In other words:


if(addr.AddressType == 2) //perfectly valid

Well, that's fine, right? I mean, we're storing 2 in the database as well, so we can't go changing the enum values. The problem is we've effectively lost the raison d'être of our enumeration, i.e. type safety. Imagine data coming in to the system from that marketing consultant. How would you perform a validity check on AddressType?



There are lots of problems with this situation, and they all revolve around how enums are implemented. In this example, there is nothing wrong with casting 6 to an AddressTypes instance... until you try to persist that value to your database and you get a referential integrity violation.


Obviously, we need a better solution. And that is where the concept of a strongly-typed string enum comes into play. Bloch's basic concept of the "typesafe enum pattern" is outline in Item 21 of his aforementioned book. More important there is his discussion about the different ways the pattern can be used, e.g. extensible implementations (inheritance) and comparable implementations (sorting). Most of what he says applies to what we are going to build, as well, despite being focused on Java.



We are going implement what I would call a typical usage of the pattern, based on my exeprience. Along the way we will leverage some of .NET's strengths and find ourselves with a much more expressive and extensible way to represent short sets of values in our systems. For now, I hope I've made the case for why we need the typesafe enum pattern and that you'll join me next time for an exposition of my .NET implementation of the pattern.

Wednesday, June 27, 2007

What IS a closure?

"Anonymous methods are not closures," is the refrain I've heard when I tell people that .NET supports closures.

Ian Griffiths thinks otherwise, and I agree.

If you don't believe me, go read up on it for your self.

A more apropos question would be--what are closures useful for in day-to-day programming?

Here's one guys attempt to answer that question, at least for the Ruby programmer. I've taken his example and turned it into C#. You really have to get to the point where closure are as accessible to you as a for loop or an if statement before you have the epiphany that make the question above seem droll.


delegate void LogDelegate(string message);
void DoSomething()
{
LogDelegate logger;
SerialNumber serialNumber = NextSerialAndLog(out logger);

logger("process 1");
logger("process 2");
logger("process 3");
}

SerialNumber NextSerialAndLog(out LogDelegate l)
{
sn = new SerialNumber();
l = delegate(string message)
{
LogInfo("DoSomething", sn, message);
};
return sn;
}

Tuesday, June 26, 2007

TODO: HTML Parser

Requirement: A continuation-based robust HTML parser that doesn't choke on all the crappy web documents out there. It would allow me to specify a qualifying filter to its generator method and iterate over qualifying nodes. The filter would be similar to an XPath expression, if not equivalent.

References:
Parsing HTML in Microsoft C#

Continuations for Curmudgeons (SAX section)

Dual (or Mixed) Mode Authentication with ASP.NET

On my current project, I was faced with the requirement to allow user logged-in on a the same domain as the server where the web application would run to use Integrated authentication, while at the same time supporting forms-based logins for users who did not have domain accounts. Users will always be directed to the same landing page when they are properly logged in.

I'm not going to explain why this work, or how it works, just what I did. I believe this solution is the simplest one you'll find if your requirements are the same as the above. This is not a general solution by any means, given the assumptions I am making.

Here's the basic idea. You're application will be configured to use Forms-based Authentication. You'll implement some strategy for determining if the request is coming from a domain user, if so you'll redirect them to a page that leverages Integrated authentication in IIS, otherwise they'll just do a normal form-based login. The Integrated authentication page will simply issue a Forms-based authentication ticket (via the ASP.NET FormsAuthentication API) and redirect the user to the landing page. Once you have an authenticated user, in either scenario, you will map that user to a logical (business-layer) User object in your application.

Essentially, you need to decouple your authentication mechanism from the logical user that you track in your application. Note that this does not preclue you from using the default Profile provider, since you are still issuing a Forms Auth ticket.

Here's what I did, specifically.

  1. Configure the web.config to use Forms-based authentication.
  2. Create a sub-folder called "Auth" and configure a web.config there to allow anonymous access to all files in that directory. This is crucial.
  3. Create two pages in the Auth directory: WebLogin.aspx and WinLogin.aspx.
  4. Configure the root web.config to use "~/Auth/WebLogin.aspx" for the forms authentication url.
  5. Build WebLogin.aspx as a normal forms authentication page, but add code to the Load event handler to check the IP address of the incoming request. If it is a domain user, redirect them to the WinLogin.aspx.
  6. In IIS, disable anonymous authentication and enable Integrated Windows authentication for the WinLogin.aspx page.
  7. In the Load event handler for the WinLogin.aspx, create a Forms Auth ticket for the logged in user.
That's the basic idea. You can use the Profile object for some light personalization, but if you need to do any auditing or authorization, you'll want to have a logical user object that you construct using either a Guid (Forms authentication) or a SID (Windows authentication).

At some point I will update the blog with a detailed implementation guide. For now, I hope this sets someone on the right track. For me, the conceptual block-buster was realizing I could make a proactive choice about how to authenticate the user, using their IP address.

Monday, June 25, 2007

Workflow Foundation ARCast

I used to be a podcast junkie, but I've been listening to more books lately. Besides .NET Rocks! I've been listening to ARCast for a long time. Well, as I'm trying to catch up on the interesting episodes, I ran across one on Workflow Foundation. Seeing as I am currently reading a book on WF, this seemed like good background noise while I work today.

The reason I'm blogging about it is that one of architects on the WF team that are on the podcast made a high-level statement about what WF can do for applications. I really liked his points, since they are easy to miss when you are studying the plumbing and theory of WF.

So, here they are:

  1. Ability to model your process such that it can react to change.
  2. Ability to model long-running processes.
  3. Ability to track processes and provide visibility into their state.
One could easily drill-down into each of those points, pointing out why the capabilities are important, how WF supports them, and how you can leverage them in your applications. In fact, I may do that in a series of posts over the next couple of days.

Saturday, June 23, 2007

Episodic Computation

Or, How I Learned to Stop Returning and Embrace Yield!

You really should stop reading this and go read this.

To this point in my career, I've found that Addison Wesley can be counted upon to deliver the more academically-minded texts on the topics I'm interested. "Essential Windows Workflow Foundation" is no exception. I am so very happy that I took this book seriously and began studying it with an eye toward a deeper understanding than just solving the problem in front of me.

I am, however, consistently struck by my own naivete when it comes to what can only be considered foundation computer science concepts. For example, I don't think I would have been fully able to articulate the differences and purposes of Subroutines, Coroutines, Continuations, Closures, and Generators. So, after an hour with Wikipedia, I am attempting share what I've learned--more for my benefit than yours. Seek first to understand, then to be understood.

Subroutines are special cases of Coroutines. Coroutines can be implemented with Continuations, while Continuations are just bookmarks for Closures. And, Generators can be thought of as a special case of a Coroutine that returns a value when it yields.

Confused? Good, that means you'll read the rest.

So, a Subroutine is (if you're a C# or VB developer) just a function.

A Coroutine is a Subroutine that can pause its execution and resume it when control flow is given back to it.

A more correct way to say it is that a Subroutine is just a Coroutine that returns only once, i.e. it always starts with a clean slate--it never resumes.

In order to resume a Coroutine, you have to keep track of where the Coroutine left off and the current state of its values (its stack frame). Bottling all that up into a kind of primitive, we call it a Continuation. So, if your language allows us to store the stack frame and an execution pointer (the last instruction), you have Continuations. If you have Continuations, you can write Coroutines. C# does this with the yield statement, which is just a fancy compiler trick for creating a state machine around the current point of execution.

A Continuation, then, requires two things to be of use: a stored re-entry point (a bookmark) and a saved variable state for a function. The later is what is known as a Closure. Specifically, a Closure looks around in its current lexical context (the written code where names (of variables) can be resolved) and packages up all that stuff into its definition, as needed. So, a Continuation can use a Closure to pick up where it left off.

Closures have a lot more general usage than just as a crutch for Continuations, but I'll leave that digression as an exercise for the reader.

Finally, Generators are just Continuations, but they return a value. To my understanding, Generators are just iterators, though one might think of a Generator as an iterator for an infinite series (think Fibonacci numbers, digits of pi, etc.); the salient difference being wether the client has to stop the iteration/generation or if the Continuation will eventually stop resuming.

What does all of this have to do with Episodic Computation or Workflow Foundation (WF)? Well, one can think of WF as an attempt to extend these and related concepts to the application level, as an attempt to create resumable programs, as an enabler of "episodic" computation. Essentially, WF wraps your higher-level imperative concepts (e.g. GenerateBillOfLading, CheckProductInventory) in "Coroutines" that can execute across processes. In other words, it is a framework for programming at the logical level.

That last statement is the Gestalt of WF. Unfortunately, that kind of expressiveness comes at a price: about USD$33

Friday, June 22, 2007

Silverlight Done Light

I recently attended a .NET user's group meeting in my area on the subject of Silverlight. I had been to a couple of these meetings before and had been generally disappointed with the quality of the presentations. The Silverlight presentation was no exception.

Don’t get me wrong; I’m really excited about Silverlight. The talk, however, met with the quality expectations I’ve been obliged to adopt with free talks. You just can’t get at any sort of depth in an hour with a naïve audience. And people tend not to prepare as well for a talk that they are giving for free.

In any event, I did find a whole bunch of stuff about Silverlight on Channel 9 over the weekend. Specifically, check out the Guthrie video and the screencasts.

  • Silverlight is a 4MB plug-in due out near the end of the year that runs on IE/FF/Safari.
  • Silverlight is a separate run-time that reuses much of what is in the .NET 3.5 runtime. The approximately 20MB .NET redistributable was shrunk to 4MB by cutting platform-specific functionality and ruthlessly removing “convenience” code (e.g. Windows Service control classes and Color.Fuscia, respectively).
  • Since .NET 2.0, Microsoft has been implementing a “platform abstraction layer” that plays a key role in providing a uniform runtime that “just works” on the Mac.
  • Silverlight includes broad support for video playback, including VC-1 (high-def).
  • Silverlight works on mobile devices.
  • Because Silverlight is effectively a subset of .NET, one can use any .NET language to write Silverlight applications. These include, but are not strictly limited to: C#, VB.NET, Python, Ruby, and C++.
  • The Silverlight tools for making creative assets are a new suite of tools called the Expression Studio: including Expression Design (vector and raster graphic asset creation: think Illustrator/Flash), Expression Web (think DreamWeaver/FrontPage), Expression Media (personal desktop organizer for media assets as well as encoding support), and Expression Blend (formerly known as Sparkle and Expression Interactive Designer). Expression Blend works natively with Visual Studio projects and is positioned as the tool for the designer on a development team. Read more at: http://www.microsoft.com/expression/
You can check out some real Silverlight applications here.

Selected Event not Firing for SqlDataSource: CancelSelectOnNullParameter

The problems I've had with declarative code are the subject of another post, but suffice it to say that I have not yet achieved "declarative enlightenment." Nevertheless, I dutifully trudge forward, using the SqlDataSource object instead of explicitly grabbing my data.


The main idea behind declarative programming is to make programmer intent more easily expressible and creating a SqlDataSource and telling a control the ID of that data source is right in-line with that idea. Unfortunately, things break down when the code running behind the declarative markup makes assumptions about your intent that are non-intuitive.


Enter the Boolean CancelSelectOnNullParameter of the SqlDataSource. This very well-named property defaults to TRUE. That's right, if you have multiple parameters on your SelectCommand and one of them is null, the SqlDataSource will not execute the SelectCommand. The page will blithely continue executing and the control(s) that are bound to the SqlDataSource will not get populated.

Interestingly, the Selecting event of the SqlDataSource will fire but the Selected event will not. This makes perfect sense: what doesn't make sense is the default. Cancelling the SelectCommand is an optimization--APIs should NEVER make an assumption around an optimization.

Using SqlCacheDependency with SQL Server 2005 in ASP.NET 2.0

Some time ago I spent an afternoon hunting around the web for the details on how the SqlCacheDependency in ASP.NET 2.0 works with SQL Server 2005. It turns out that the class performs an automatic configuration of a SQL Server 2005 query notification. Not sure what that is?Using and Monitoring Sql Query Notifications This is a truly excellent article to get started.



I've included the relevant links to SQL Books Online and quoted particularly relevant passages in italics. I certainly don't intend this post to be a "how-to", but I hope it helps the reader to get her arms around how to use the SqlCacheDependency and query notifications (by extension).



First, we only need to enable the service broker. Notification services is not utilized, surprisingly.



Using Query Notifications



The Database Engine uses Service Broker to deliver notification messages. Therefore, Service Broker must be active in the database where the application requests the subscription. The query notification functionality does not require or use Notification Services. Query notifications are independent of event notifications.



Secondly, we cannot use query notifications for just any type of query. There are a lot of rules on how the query is constructed that my restrict what data you can cache with the SqlCacheDependency.



Creating a Query for Notification



The query notifications functionality builds on the change detection mechanisms that the Database Engine uses to maintain indexed views. The requirements and restrictions for statements in a query for notification are similar to the requirements and restrictions for an indexed view.



It seems the overhead associated with these query notifications is mainly on updates. I'm guessing that SQL Server uses a mechanism similar to its query plan caching/reuse mechanism to identify similar queries in subscriptions.



Planning for Notifications



When query notifications are active on a table, updates to the table are more expensive. The Database Engine performs extra work to check subscriptions and, if necessary, generate notifications. Reusing internal templates helps to minimize the overhead per subscription. Therefore, you should use query notifications only for applications that submit queries with a similar structure. An application that submits queries with different structures should not use query notifications.



In addition to having normal execute and select permissions, the application user needs to have a couple of other permissions. Although granting DDL rights to the application seems deeply wrong to me, there is a wonderful article on granting minimum rights to the application.You can read more about them here.



GRANT SUBSCRIBE QUERY NOTIFICATIONS TO <database_principal>



GRANT RECEIVE ON QueryNotificationErrorsQueue TO <database_principal>



Because the SqlDependency object in the ASP.NET runtime auto-magically creates the Service Broker service, queue, and notification procedure, the application user also needs the following rights.



GRANT CREATE PROCEDURE TO <database_principal>



GRANT CREATE QUEUE TO <database_principal>



GRANT CREATE SERVICE TO <database_principal>



Actually, the class in the ASP.NET runtime that actually sets all this up is called the SqlConnectionContainer. It's quite the sophisticated class, doing all of the heavy-lifting. From what I gather, it creates procedures (named SqlQueryNotificationStoredProcedure-* where * is a GUID) that drop the service and queue when the conversation timer expires. I'm a little fuzzy on the low-level implementation, but I wanted to know why it needed these rights. So, I used Lutz Roeder's .NET Reflector to take a peek at what is going on inside the class.



The SQL Books online mentions that the user that attaches a query notification request to a command must have the following:



GRANT SEND ON SERVICE:://theservice to <database_principal>



However, the service doesn't exist until the SqlConnectionContainer creates it, so the SqlConnectionContainer grants the SEND ON SERVICE to a specific role: sql_dependency_subscriber. This role does not exist and must be created if you need to lock-down permissions as in the article above.