On this page.... RSS 2.0 | Atom 1.0 | CDF
Love the Bomb
Silverlight Controls
Wrox Silverlight 2 Programmer's Reference Early Access
Podder Skinning Contest Extended
DeveloperDeveloperDeveloper Ireland
Silverlight 2 Sample Application - faceOut
Blog Notes Live Writer Plug-in
Favor Thoughtful Adherence Over Blind Adherence
Web Services Best Practices
Me? An INETA Speaker?
Are You Passionate?
Tampa Code Camp 2007 [Download]
Review: Essential Windows Presentation Foundation
How Would You Like Your Bits?
Reminder - NYC Code Camp!
SYS-CON Readers' Choice Voting Guide
blogmailr Beta
New Jersey CodeCamp III - This Weekend!
Got ASP.NET AJAX? Get ASP.NET AJAX for NetAdvantage!
New Web Site Released for Infragistics!
BEWARE the EnableCaching of XmlDataSource
Tulsa Tech Fest Results Are In
Adding Custom Browser Capabilities in ASP.NET
Tulsa TechFest 2006
Strongly-Typed Profiles in Web Application Projects (WAP)
Web Dev with IE
Output Caching Profiles and Custom Caching
Oracle ELMAH Provider
Right-Click to Run ASP.NET Development Server
Live from Redmond Series 2 from the .NET FX Product Teams
Blog Reading and Authoring Review
The Cat's Out of the Box: The ASP.NET Sand Box
NJ.NET User Group Meeting TONIGHT!
Accelerating Web Dev with Enterprise Library 2 Session at TechEd
New Blog at Infragistics
VS 2005 Web Application Project V1.0 Released
More Oracle Gotchas
Updated DasBlog
Visual Inheritance with User Controls in ASP.NET 2.0 Web Applications
Launching New Convenience Categories
OPC Odyssey
InternalsVisibleTo is Friendly
Windows XP 64bit Has IIS 6
dotNetTemplar et Infragistics
Is Generic Database Programming a Myth?
Major Binding Gotcha with Arrays and ICustomTypeDescriptor
Pretty Nifty Community Site - Community-Credit.com
No Promotable Single Phase Enlistment (PSPE) for Oracle
Gotcha on Custom ASP.NET Role Providers
VS 2005 Web Application Project Release Candidate Now Available
I Got My Pubs Back
Cool ASP.NET 2.0 Feature of the Day
Go Vote for ASPAlliance!
Attention Software/IT Architects!
"What is Your Quest?" - Determining the Difference Between Being an Architect and Being a Developer
SoCal's DE Acknowledges that Florida has the Best Developer Community in the World
Microsoft Advances in OOD
Tracking ASP.NET Shutdowns
Scripting Execute for All Stored Procedures
Professional ADO.NET 2: Programming with SQL Server 2005, Oracle, and MySQL
PageMethods Are Cool!
Unofficial Abbreviation for Windows Workflow Foundation
Linux RULZ!
What About .NET in WinFX?
The Outsourcing Threat
Move Aside DEEP Thought!
VB Grows Up
Spang - Wha's That All About??
ASPAlliance is now Active Software Professional Alliance
Good Stuff in MSDN Mag
Where Were You?
Atlas is Alive!
Chalk One Up for the Community!
Indigo Roadshow in Tampa
Windows Vista Unveiled
Promising ASP.NET Session Manager
Code Camp Done (Presentation Download)
Tampa Code Camp is Full (for Real)
Come Write for ASPAlliance.com!
Tampa Code Camp is for Everyone!
Are You a WSE 3 Expert?
Web Service Enhancements (WSE) 3.0 and X.509
Upcoming Tampa DNUG
Registration for Tampa Code Camp is Now Open!
Visual Studio 2005 et al Launch Date (and Other Cool Stuff)
ADO.NET 2.0 Provider for Active Directory
Do You Want to Be Famous? :)
Pre-order Now!!
Project Rally: Episode II
SoCal is Charging for Code Camp!
Wow.. I Can Actually Understand This
No More Code Beside
Cast to Derived Type from Base
Snazzy ASP.NET Lifecycle Diagram
Easier Story for Metadata Polymorphism (in C#)
Get an Early Start on the Quickstarts
System.Attribute Overrides Object.Equals; why?
Go Vote..
Sharing Impersonated Identity with ThreadPool
I Don't Care What You Call It
Tracking Finally Working...
Tampa DNUG - 3/23/2005 : Intro to O/R Mapping
Namespace Paralysis
ASPAlliance.com Gets More Perf Work
dotNetTemplar Joins ASPSOFT, Inc.
New Experienced-Level Job Opening at GTE Federal Credit Union
Sample Code for CoDe Magazine Article
Introduction to Object-Relational Mapping for .NET
A Critical Eye on SO(A)
NUnit Adds Two Very Helpful Attributes
Balancing Inline Comments with Reusability
# Wednesday, September 14, 2011

Courtesy of ZDNet

Much ado has been made in the recent months about the impending death of <insert name of MS UI stack here>. This week, at BUILD, Microsoft has finally stepped up and shown us what their view of the future is. Note that, in their architecture diagram, the current "desktop" technologies are represented as a peer. Included in the right side is Windows Forms, which of any .NET technology has long been exaggerated as dead; and yet it is still alive.

The point is, despite all the "future is Metro" talk by other analysts (e.g., Mary Jo herself), the fact remains that these are peer technologies, and Microsoft is not "killing" anything in the right side. In fact, there is no such intent expressed implicitly or explicitly.

That's not to say, of course, that nothing has changed. That's not to say that we can or should ignore Metro/WinRT (duh!). But there seems to be this common knee jerk reaction when a new technology is released to say that the current ones are now dead or somehow not worth investing in further. That reaction just doesn't reflect reality.

As impressed and (mostly) happy as I am about the direction expressed in the Win8 stack, we need to keep in mind that we are still in the early stages, still in gestation. The baby isn't even born yet, and once it is born, it will take time to grow up and mature. In the meantime, we have these mature, stable, currently released technologies that are great to build on.

I think it's great that Microsoft has released this stuff early. I like that about them better than other tech vendors. Although they've been more tightlipped about this than any other tech they've released, the fact remains we have plenty of time to plan, prepare, design, prototype, explore, and ultimately build for the new stack. In the meantime, we can still safely invest in the current technologies.

The future is uncertain. That is the nature of the future. Devs need to quit unrealistically asking Microsoft to guarantee them the future of technology. We know that it would be bad business for Microsoft to kill off these current technologies; so bad, we should feel it as a positive guarantee that they are here to stay for any future that we should be currently planning for. We will always have legacy. Someday, the Win8 stack will, I assure you, be legacy.

The things that remain constant are:

  • Understand the needs of your application context.
  • Understand the capabilities, strengths, and weaknesses of the various technologies you can build on, including current investments.
  • Understand your team's capabilities, strengths, and weaknesses, including current investments.
  • And choose the technology stack that makes the most sense, best balancing all these considerations, realizing that you won't make all the right choices (in retrospect) and that this is just life as a software professional.

Everything else is just a bunch of unnecessary worry and hullaballoo.

Wednesday, September 14, 2011 9:58:18 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [1]  | 
# Wednesday, October 29, 2008
The good folks over at Microsoft have released their Silverlight Toolkit today (or I guess yesterday, now).  It's a good start to complement what you get in the core/box.  I personally found the AutoCompleteBox probably the most interesting control, and the theming capabilities being introduced with the ImplicitStyleManager are promising, too.  I also like the way the team is running the toolkit project on codeplex and all.  Shawn Burke (of Ajax Control Toolkit fame) is a great guy to be leading that group of talented folks.

Of course, in my humble opinion ;-), no discussion of Silverlight controls would be complete without looking at the outstanding work that Infragistics is doing, particularly in the data visualization space.  In our current CTP that you can download now, we have the xamWebChart, xamWebGauge, xamWebMap, xamWebTimeline, and xamWebZoombar.

If you go to http://infragistics.com/silverlight, you can read about all those controls, but I encourage everyone to just go play with them in our really awesome (if I do say so myself!) Silverlight controls samples browser.  I mean, it is just plain fun tweaking around with it.  I could sit and watch the datapoint transitions all day, and the chart zooming is freakin' cool.  Needle dragging gauge, overview plus detail implementation for the map, timeline...  Heck, who am I kidding?  It's all sweet!


I'm not just saying that because I work there; I really was just having fun and am frankly impressed with the work our guys are doing.  Kudos to our entire Silverlight team!   Great job, guys!  I'd name names, but I'm bound to forget someone.  You know who you are!

And the fact that I'm playing with this in Safari on my Mac over my crappy hotel internet access just makes it that much cooler and fun.  You gotta love Silverlight! 

If you're interested more in Line of Business (e.g., Outlook bar, hierarchicial data grid, tree, etc.), check out our info on Silverlight LOB controls.  According to our roadmap published there, you should see a CTP of our first release towards the end of this year.  Silverlight rocks, and I'm looking forward to seeing it develop and being a part of making it even better.

You should stop by our booth at PDC, if you haven't already, and ask about all this.  We're Booth #201 (about 3 down on the left from the middle entrance).  There's still some time left, and you can pummel the guys and gals there with your questions.  Of course, you can always just call, chat, or email someone as well (or use the contact link on this blog, and I'll put you in touch). 

Also, feel free to stop me in the hall at PDC if you want.  I won't bite.  Everyone says I look like Kevin Smith (which is why I was Silent Bob at the Expo reception Monday), so you should be able to recognize me, even without the trenchcoat. :)  Now I have to get to sleep so I can keep my promise and not be a zombie (and ergo not bite).  G'night!

Wednesday, October 29, 2008 4:10:19 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, July 29, 2008

Wrox has started a new thing as of late they're calling Wrox First.  It's essentially a wiki of the book that I and my fellow Silverlight 2 authors are working on--Silverlight 2 Programmer's Reference.  Not only do you get early access, you can also shape how the book develops by making comments and suggestions.  My understanding is that it's just $19.99 and will get you access to drafts, revisions, and the final chapters as they are in the book for up to a year after publishing. 

Seems like an interesting option for those who want the book and sample code now rather than waiting until later this year when it is published.  Let me know what you think!

Tuesday, July 29, 2008 2:35:41 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, July 2, 2008

Phwew!  I just moved yesterday (actually all weekend and yesterday and still more unpacking to go now!).  Man, all that moving is starting to wear, but we're very happy in the new place.  A lot more space to make room for number four! :)

On to the point.  Josh Smith has extended his Podder skinning competition.  For those who don't know, Podder is this nifty WPF-based podcasting client/player.  He designed it so that you can completely change the look and feel using skins.  I suggested a better term would be skeletoning, since you can change the structure in addition to the styling, but so far that hasn't caught on.  Be sure to tell him you think that's a better term!

Wednesday, July 2, 2008 9:39:04 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, April 15, 2008

A few buddies of mine, Phil Winstanley and Dave Sussman, have asked me to pass along that they're doing an upcoming DeveloperDeveloperDeveloper event in Galway, Ireland on 3 May.  So on the off chance I have some readers in that area, I figured I'd pass it along.


Tuesday, April 15, 2008 5:13:13 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, March 17, 2008

For those of you that don't keep an eye on my work blog, my team at Infragistics just published a new Silverlight 2 sample application, faceOut, using prototypes of Infragistics' Silverlight controls.  If you're interested in Silverlight 2 and/or interested in what Infragistics is doing with Silverlight, you should check it out.

Monday, March 17, 2008 8:54:27 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, December 22, 2007

I've been getting friendly with Windows Live lately, and after getting terribly tired of having to switch to HTML view in Windows Live Writer in order to insert a note (could be a footnote or endnote depending on how you look at it), I decided to see if I could write a plug-in to make my life easier.

So was born the Blog Notes plug-in.  Unfortunately, there is no extensibility for just marking up existing text (e.g., adding a superscript button to the markup toolbar), so I had to go with the option to insert some HTML using the  interface.  I really was trying to keep it simple and lightweight (for my own sanity), so it is pretty basic.

The functionality is pretty straightforward.  Thanks to Mark James for the free icons.  Once the plug-in is installed, you should see an "Insert Blog Notes..." option in the Insert pane on the right side as shown below.

Insert Blog Notes in Insert Pane

Clicking on it brings up the Blog Notes dialog:

Blog Notes Dialog

Clicking "New Note" will insert a new superscript number (the next one in the sequence).

Clicking "Reference Note" will insert the selected number as superscript.  You can also just double-click the number to do that.

The "Notes Section" button will insert a notes section.1

Lastly, "Write Note" simply adds the selected note plus a period and couple spaces.

As you can see, it's pretty basic, but it saves a few seconds for each note (assuming you bother to switch to HTML view, find the number, and put <sup></sup> tags around it like I do [did]).  You can also tweak one option/setting.  Go to Tools -> Options, and select the Plug-ins tab:

Live Writer Plug-ins Options

Clicking Options... on the Blog Notes plug-in brings up a tres simple dialog:

Blog Notes Options

This one option will toggle whether or not the plug-in uses in-page anchor links for the notes so that the superscript numbers would link down to the corresponding note in the Notes section.  I originally added this feature without realizing the implications.  Because blog posts are often aggregated and otherwise viewed in unexpected places, using in-page anchors is iffy at best.  Community Server seems to strip them out, and dasBlog keeps them, but since it emits a <base /> tag to the site root, all of the anchor links are relative to the site homepage instead of the current post, which effectively renders them useless.  I looked at the dasBlog code where this happens, and it's in the core assembly.  I was concerned what side effects changing it to use the current URL would have, so I didn't do that.  But if you have blog software that will let you use this feature, by all means, enjoy!


  • Because of the way the plug-in framework works, I use a static/shared collection to keep track of the notes.  This means it acts a tad goofy if you close out of Live Writer or write multiple posts while it is open.  If you close and come back to a post, the notes count is reset.  To "fix" this, just re-add however many notes you had (if you want to bother).  If you write multiple posts, you just have to deal with it.  I don't know if there is post-local storage for plug-ins, but I didn't have time to dig into it.
  • Your mileage may vary.  I wrote this mainly to save myself time and get familiar with the Live Writer extensibility model, so it ain't a finished product to be sure.

Get It!
Since there are numerous tutorials on the Web (that I learned from) to write Live Writer plug-ins, I won't go into those details here, but you're welcome to download my code and learn from it directly if you want.  I think I have comments and such in there.

  • Download the Plug-in Only - If you just want to use this plug-in, this is what you want.  Drop the DLL into your plug-ins directory and go (typically C:\Program Files\Windows Live\Writer\Plugins).
  • Download the Source Code - This is a VS 2008 solution for those who want to learn, enhance, extend, whatever.  The license is more or less the MIT license.  You'll need Live Writer installed to reference its API.

1. This is the "Notes Section."  The button adds the "Notes" header and writes out any existing note numbers.

Saturday, December 22, 2007 2:07:12 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, December 11, 2007

Far be it from me to put words in Phil's mouth, but I hope that folks recognize that his post about favoring composition over inheritance is not specifically about that one best practice (the comments seem to indicate this is being missed).  It's pretty clear to me that the thrust of that post is around a philosophical approach that he thinks the ALT.NET community should make.

Two things stand out from Phil's post in this respect: 1) don't appeal to authority, and 2) don't organize yourself around a set of technical principles (best practices), but rather organize yourself around the non-technical values of independent thinking and desire to improve.  I hope that everyone can agree that these latter two values are good ones that should indeed be encouraged.

That said, should a community like ALT.NET eschew forming a more formal consensus on technical best practices?  I tend to think not.  While independent, critical thinking is valuable, it is not the summit of perfection.  The summit of perfection, in the realm of ideas at least, is conformance with truth (what actually is versus what I think is), and independent thinking at odds with what is true is not only not valuable in itself, it can be downright detrimental. 

For instance, what if you independently and critically think that security and privacy are not important aspects of the online banking application you are tasked with building?  Is that kind of independent, critical thinking valuable in itself?  Or will it potentially lead to great harm?  Independent, critical thinking is valuable only in as much as it deepens one's understanding of and conformance to truth.

So I think that there is value in a community such as ALT.NET expending the effort to define principles through critical thinking and argumentation that it will hold up as ideals, i.e., things that seemed to be most in accord with the truth as we know it.  This is where things like patterns and best practices come into play; it is the shared, accumulated wisdom of the technical community.

Now what about the broader idea of eschewing appealing to authority?  Far be it from me to claim to be an authority in logic, but it seems to me that all appeals to authority are not invalid (the wikipedia article Phil links to discusses this to some degree but does not go far enough, in my estimation).  The valid reasons for appealing to authority are discussed at the bottom of that article: 1) not enough time and 2) concern at one's ability to make the other understand the reasoning underlying the truth being expressed.

In terms of logic, it is not a fallacy to appeal to an authority on a topic that is accepted by all those involved in an argument.  We're talking about presuppositions here, and without them, we'd never get anywhere in our search for truth.  If you always have to argue from first principles (if you even acknowledge those), you simply get stuck in a quagmire.  In terms of the topic at hand, if folks accept (as they generally do) that the GoF et al are authorities on the subject of OOD, then it is valid, logically speaking, to appeal to their authority to establish the principle that you should favor composition over inheritance.

The thing to watch out for in appeals to authority is 1) thinking that the authority is incapable of being wrong and 2) ensuring that the parties involved accept the authority.  With the latter, you simply cannot argue (or at least the argument won't carry weight) from authority if the authority is not accepted.  With the former, unless it is a presupposition shared by those involved that the authority is indeed infallible, you should keep in mind that even if you buy into the authority's credentials, it is still possible that the authority can be wrong.

So I would nuance what Phil says and say that if the ALT.NET community agrees that GoF is an authority, it is valid to appeal to them, while remaining open to criticism of the concepts involved (even those backed by an authority).  The authority adds logical weight; it does not impose absolute authority.

We just don't have time to argue everything from first principles.  Others who are generally acknowledged to be qualified have already taken the time to research, think about, and propose some good patterns and practices, and unless there is good reason to object, there is no need to rehash those.  Instead, I'd suggest that the community focus on spreading knowledge of these patterns and practices all the while refining them, functioning essentially as a group in the way that Phil recommends individuals function--thinking critically and always working to improve.  Doing this will help ensure that the community does not fall into a quagmire of unnecessary argumentation, and it will ensure that the patterns and practices that they agree upon can be continuously refined and enhanced as new technologies emerge and greater wisdom is gained over time. 

Further, it gives the group a purpose that has meaning.  After all, if the group's message is only "think for yourself and be all that you can be," there isn't much of substance to say after that.  On the other hand, because it is a technical community that espouses that philosophy, it should take that philosophy on itself (as a group, not just the individuals in it).  I would suggest this includes establishing greater consensus on best practices and patterns and then spreading the word about them to others.  Be better together. :)

You see, it is not about setting down an infallible manifesto and excluding those who disagree, which is I think more than anything what Phil is concerned about.  However, it also isn't about best practices just being true for you but not for me (best practices relativism?).  Put another way, I suggest ALT.NET should favor thoughtful adherence to best patterns and practices, not blind adherence.

Tuesday, December 11, 2007 9:56:00 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [2]  | 
# Saturday, September 15, 2007

As I sit here on my deck, enjoying the cool autumn breeze1, I thought, what better thing to write about than Web services!  Well, no, actually I am just recalling some stuff that's happened lately.  On the MSDN Architecture forums and in some coding and design discussions we had this week, both of which involve the question of best practices for Web services.

Before we talk about Web services best practices, it seems to me that we need to distinguish between two kinds of application services.  First, there are the services that everyone has been talking about for the last several years--those that pertain to service-oriented architecture (SOA).  These are the services that fall into the application integration camp, so I like to call them inter-application services. 

Second, there are services that are in place to make a complete application, such as logging, exception handling, data access and persistence, etc.--pretty much anything that makes an application go and is not a behavior of a particular domain object.  Maybe thinking of them as domain object services would work, but I fear I may already be losing some, so let's get back to it.  The main concern within this post are those services using within an application, so I call them intra-application services.

It seems like these latter services, the intra-application ones, are being often confused with the former--the inter-application services.  It's certainly understandable because there has been so much hype around SOA in recent years that the term "service" has been taken over and has lost its more generic meaning.  What's worse is that there has been a lot of confusion around the interaction of the terms Web service and just plain service (in the context of SOA).  The result is that you have folks thinking that all Web services are SO services and sometimes that SO services are always Web services.

My hope here is to make some clarification as to the way I think we should be thinking about all this.  First off, Web services are, in my book at least, simply a way of saying HTTP-protocol-based services, usually involving XML as the message format.  There is no, nor should there be, any implicit connection between the term Web service and service-oriented service.  So when you think Web service, don't assume anything more than that you're dealing with a software service that uses HTTP and XML. 

The more important distinction comes in the intent of the service--the purpose the service is designed for.  Before you even start worrying about whether a service is a Web service or not, you need to figure out what the purpose of the service is.  This is where I get pragmatic (and those who know me know that I tend to be an idealist at heart).  You simply need to determine if the service in question will be consumed by a client that you do not control. 

The reason this question is important is that it dramatically affects how you design the service.  If the answer is yes, you automatically take on the burden of treating the service as an integration (inter-application) service, and you must concern yourself with following best practices for those kinds of services.  The core guideline is that you cannot assume anything about the way your service will be used.  These services are the SO-type services that are much harder to design correctly, and there is tons of guidance available on how to do them2.  I won't go in further depth on those here.

I do think, though, that the other kind of services--intra-application services--have been broadly overlooked or just lost amidst all the discussion of the other kind.  Intra-application services do not have the external burdens that inter-application services have.  They can and should be designed to serve the needs of your application or, in the case of cross-cutting services (concerns) to serve the needs of the applications within your enterprise.  The wonderful thing about this is that you do have influence over your consumers, so you can safely make assumptions about them to enable you to make compromises in favor of other architectural concerns like performance, ease of use, maintainability, etc.

Now let's bring this back to the concrete question of best practices for intra-application Web services.  For those who are using object-oriented design, designing a strong domain model, you may run into quite a bit of trouble when you need to distribute your application across physical (or at least process) tiers.  Often this is the case for smart client applications--you have a rich front end client that uses Web services to communicate (usually for data access and persistence).  The problem is that when you cross process boundaries, you end up needing to serialize, and with Web services, you usually serialize to XML.  That in itself can pose some challenges, mainly around identity of objects, but with .NET, you also have to deal with the quirks of the serialization mechanisms.

For example, the default XML serialization is such that you have to have properties be public and  read-write, and you must have a default constructor.  These can break encapsulation and make it harder to design an object model that you can count on to act the way you expect it to.  WCF makes this better by letting you use attributes to have better control over serialization.  The other commonly faced challenge is on the client.  By default, if you use the VS Add Web Reference, it takes care of the trouble of generating your service proxies, but it introduces a separate set of proxy objects that are of different types than your domain objects.

So you're left with the option of either using the proxy as-is and doing a conversion routine to convert the proxy objects to your domain objects, or you can modify the proxy to use your actual domain objects.  The first solution introduces both a performance (creating more objects and transferring more data) and a complexity (having conversion routines to maintain) hit; the second solution introduces just a complexity hit (you have to modify the generated proxy a bit).  Neither solution is perfectly elegant--we'd need the framework to change to support this scenario elegantly; as it is now, the Web services stuff is designed more with inter-application services in mind (hence the dumb proxies that encourage an anemic domain model) than the intra-application scenario we have where we intend to use the domain model itself on the client side.

If you take nothing else away from this discussion, I'd suggest the key take away is that when designing Web services, it is perfectly valid to do so within the scope of your application (or enterprise framework).  There is a class of services for which it is safe to make assumptions about the clients, and you shouldn't let all of the high-falutin talk about SOA, WS-*, interoperability, etc. concern you if your scenario does not involve integration with other systems that are out of your control.  If you find the need for such integration at a later point, you can design services (in a service layer) then to meet those needs, and you won't be shooting yourself in the foot trying to design one-size-fits-all services now that make so many compromises so as to make the app either impossible to use or very poorly performing.

My own preference that I'd recommend is to use the command-line tools that will generate proxies for you (you can even include a batch file in your project to do this) but then modify them to work with your domain model--you don't even need your clients to use the service proxies directly.  If you use a provider model (plugin pattern) for these services, you can design a set of providers that use the Web services and a set that talk directly to your database.  This enables you to use your domain model easily in both scenarios (both in a Web application that talks directly to the db as well as a smart client that uses Web services). 

It requires a little extra effort, but it means you can design and use a real domain model and make it easier easier to use by hiding the complexity of dealing with these framework deficiencies for consumers of the domain model.  This is especially helpful in situations where you have different sets of developers working on different layers of the application, but it is also ideal for use and reuse by future developers as well.

One of these days, I'll write some sample code to exemplify this approach, maybe as part of a future exemplar.

1. The weatherthing says it's 65 degrees Fahrenheit right now--at 1pm!
2. My observation is that it is safe to assume that when other people talk about services and Web services, these are the kind they're thinking of, even if they don't make the distinction I do in this post. 

Saturday, September 15, 2007 6:00:03 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, September 10, 2007

I wasn't going to post about it, but after reading Don's post, I realized that I should so that I can thank those involved in presenting me with this honor.  I was surprised when I was contacted about being nominated to be an INETA speaker, and I was even more surprised when I heard that I'd been voted in.  Looking over the folks on the list, I feel hardly qualified to be named among them.

So without further ado, let me thank David Walker (who's an all around great guy and VP of the Speakers Bureau), Nancy Mesquita (who I've not had the pleasure to meet personally but has been very helpful in her role as Administrative Director), as well as everyone else involved on the Speaker Committee and others (whom I know not of specifically) in welcoming me into the INETA speaker fold.  It's a great honor--thank you. 

Now, I have to get back to work!  My group, UXG, just released Tangerine, the first of our exemplars, and now we're on to the next great thing!

Monday, September 10, 2007 10:19:19 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [1]  | 
# Monday, July 30, 2007

Are you passionate about software development?  Do you love to share your knowledge with others?  Do you like working in a vibrant, fun culture working on the latest and greatest technologies with other smart and passionate people?  If so, I think I may have your dream job right here.

We're looking for another guidisan to help craft guidance using best practices for .NET development.  The word guidisan ('gId-&-z&n) comes from a blending of "guidance" and "artisan," which really speaks to the heart of the matter.  We're looking for software artisans who have the experience, know-how, and gumption to explore strange new technologies, to seek out new applications and new user scenarios, to boldly go where other developers only dream of going in order to provide deep, technical guidance for their colleagues and peers.

What do guidisans do? 

  • Help gather, specify, and document application vision, scope, and requirements.
  • Take application requirements and create an application design that meets the requirements and follows best known practices for both Microsoft .NET and Infragistics products.
  • Implement applications following requirements, best practices, and design specifications.
  • Create supplemental content such as articles, white papers, screencasts, podcasts, etc. that help elucidate example code and applications.
  • Research emerging technologies and create prototypes based on emerging technologies.
  • Contribute to joint design sessions as well as coding and design discussions.

What do I need to qualify?

  • Bachelor’s Degree.
  • 4+ years of full-time, professional experience designing and developing business applications.
  • 2+ years designing and developing.NET applications (UI development in particular).
  • Be able to create vision, scope, and requirements documents based on usage scenarios.
  • Demonstrated experience with object-oriented design; familiarity with behavior-driven design, domain-driven design, and test-driven development a plus.
  • Demonstrated knowledge of best practices for .NET application development.
  • Accept and provide constructive criticism in group situations.
  • Follow design and coding guidelines.
  • Clearly communicate technical concepts in writing and speaking.

If you think this is your dream job, contact me.  Tell me why it's your dream job and why you think you'd be the next great guidisan.

Monday, July 30, 2007 3:01:27 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [1]  | 
# Sunday, July 15, 2007

Thanks to all who came to my "suave sessions" session yesterday at Tampa Code Camp.  Now you're all "it getters," and you get some free code, too.

Download the Session Management Code


Sunday, July 15, 2007 7:50:42 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [1]  | 
# Sunday, April 29, 2007

Essential Windows Presentation Foundation Essential Windows Presentation Foundation is precisely what the title says it is.  What more can you ask for in a book?  There are already several books on the RTM of WPF, and there are bound to be more.  The unique value this one has is that it is written by Chris Anderson, who as most know, was an instrumental architect in designing WPF, and this (along with his direct connection to the others who worked on it) gives him insight that you just otherwise can't get. 

In particular, I like that he often provides the thinking that went into particular design decisions.  He readily admits in several places that the design of this or that was hotly debated, and one can only imagine that they would be.  Having worked at a few commercial software vendors myself, I know how difficult it can be to know the best way to design a thing, and it can only be more challenging as your audience widens. 

After this, the main thing that makes the book valuable is that it is deeply conceptual.  The point of the book is not to be a reference, a recipie book, or a smattering of tutorials.  Rather, the book provides, in a coherent form, the key principles underlying the different aspects of WPF.  And by elaborating these principles, Chris establishes a strong sense that the Foundation was designed in a similarly coherent manner.

My favorite chapters were the one on Data, the one on Actions, and the Appendix.  For a solutions architect and developer, these I think provide the most interesting meat.  Of course, these types will likely want to delve into the first three chapters as well.  In fact, the only one that I'd suggest you can probably get away with skipping is the one on Visuals; I found this one pretty dry and hard to push through.  Designers and those more interested in graphics per se will likely enjoy these.

The chapter on Styles took me by surprise, but then, that's because the concept of styles in WPF is a tad surprising.  Being the language-oriented person that I am, I am a bit bothered by the choice of Style to encompass everything that you can do with styles in WPF.  Needless to say, it's not just UI goodness--devs will need to be pretty familiar with this stuff.

Other than that, my only contention is with the assertion that apps today are all about data.  This won't come as a surprise to those who've read my articles or talked to me about architecture much, but despite my philosophical objection, when it comes to UI, I'll admit that LOB apps are in fact largely about the data, i.e., largely about displaying and manipulating data since thus far, we seem to have mainly used computers to help with data storage and retrieval.  In any case, it is certainly important to have good data binding mechanisms in the UI, and I have to say, WPF nails this better than any UI tech I've bumped into thus far.

But I digress.  The book is good; I recommend it as a starting point or to complement other WPF learning resources.  It is the essentials with which you can start effectively creating WPF applications.  You'll need the docs and/or other more comprehensive books to really figure it all out, but you should read this one regardless.

Sunday, April 29, 2007 8:12:40 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, April 27, 2007
Just a one question survey. 
If you are evaluating a software product, what do you prefer to do:
A) Download everything, including help, samples, SDK, etc. at once, even if it may be half a gig.
B) Just download the product bits first and then either download the help, samples, SDK, etc. separately as you need them (or never download those and just use online help/samples).
C) Download a shell installer that lets you pick what you want and only downloads/installs what you pick?
D) Try out the bits in an online VM environment.
E) Other, please specify.
You can either just pick one or put them in order of preference.
Thanks in advance for any opinions!
Friday, April 27, 2007 2:31:06 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [1]  | 
# Thursday, March 1, 2007

Don't forget!  This Saturday is NYC Code Camp III!  Unfortunately, I won't be able to make it as I'm helping to prepare for our upcoming 2007 Volume 1 launch next week.  We've got some great stuff in the works from the User Experience Group, so keep an eye out for it. :)

Thursday, March 1, 2007 11:39:10 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, December 19, 2006

It's that time again.  Time for the SYS-CON Readers' Choice Awards voting.  Actually, it's been that time for a little while now; I'm just slow.

Infragistics has been nominated for several categories in several publications, so if you like Infragistics or even if you're looking for a way to kill a few minutes at the airport, go vote for us.

Here's your friendly voter's guide to make your life easier (note that if you don't know or prefer any choice in a particular category, you can just click Continue to move on):


#11 - NetAdvantage for JSF

#12 - NetAdvantage for JSF

#20 - JSuite

#24 - NetAdvantage for JSF

#28 - NetAdvantage for JSF


#4 – NetAdvantage for .NET

#14 – NetAdvantage for .NET


#3 – NetAdvantage for ASP.NET

#6 – Infragistics Training and Consulting

#7 – Infragistics Training and Consulting

#8 – NetAdvantage for ASP.NET


#3 – NetAdvantage AppStylist

#4 – Infragistics Training and Consulting

#5 – Infragistics NetAdvantage for .NET

#10 – TestAdvantage for Windows Forms

Tuesday, December 19, 2006 6:28:11 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, November 13, 2006

Last week, the head geek at Telligent told me about this new service they’re offering called blogmailr.  It’s a pretty cool concept; it allows folks to post to their blogs using email.  So I thought I’d try it out.  If this works or not, it went through blogmailr.  It’s worth a look.

Monday, November 13, 2006 11:28:40 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 

I was just reminded by our local Dev Evangelist, Peter Laudati, that we've got our third NJ CodeCamp coming up this weekend.  Code camps are a fun way to get to know other local devs, learn some cool stuff, and generally get at least a free lunch!  So you should go!

Monday, November 13, 2006 9:55:40 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, November 10, 2006

So Infragistics had a pretty cool release today, if I do say so myself.  We've released a beta patch for our NetAdvantage for ASP.NET product that supports Microsoft's ASP.NET AJAX Beta 1 and Beta 2. 

Support Details

  • Our controls will register themselves with the UpdatePanel to ensure proper operation within it.
  • Our Javascript Client-Side Object Model (CSOM) continues to work alongside the Microsoft AJAX Library.
  • Infragistics controls will not interfere with the Microsoft AJAX Library.
  • Infragistics controls can be embedded in and work with ASP.NET AJAX Control Toolkit controls.

I'm pretty pumped about ASP.NET AJAX, especially the Microsoft AJAX Library.  It should make client-side development across browsers much easier, and with the AJAX Extensions, it helps make adding AJAX to your apps in ASP.NET considerably easier, and the UpdatePanel is an indisputable help in that respect.

Infragistics is committed to the ASP.NET AJAX platform.  We'll be supporting it throughout the beta, the release, and beyond.  We've been adding AJAX-powered features since 2004, and it is only going to get better for us and everyone else thanks to the new platform and tool enhancements that are coming down the line.

Friday, November 10, 2006 7:39:04 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, October 26, 2006

Today we launched our new web site.  It was not just a simple update; we revamped the whole deal and made it Web 2.0 compliant <grin>.  If you remember our old site, I trust you'll immediately see the improvement.  Please take a minute to check it out and let me know what you think.  Also, if you run into any problems with it, please feel free to let us know.

Thursday, October 26, 2006 7:24:38 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [3]  | 
# Monday, October 23, 2006

I just spent an hour or more that I DON'T HAVE debugging a mysterious caching issue.  I suppose in some cases it might be obvious, but in this one, it was not.  To sum up, we're using an XmlDataSource control generically and setting its Data property programmatically (and using an XSL--don't know if that matters). 

Anyways, apparently the dang control defaults to "cache indefinitely" and won't refresh until the file it depends on changes.  I guess the thing is that it doesn't look for changes when you set the Data property, so it caches indefinitely to be sure.  Set EnableCaching to false, and voila, the problem is solved.

This just highlights a rule that all general APIs should follow--don't do any automatic caching.  You can't account for all the ways your customers will use your stuff, so just don't do it.  It's not hard to make them flip a bit to turn it on. 


Monday, October 23, 2006 10:39:43 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, October 17, 2006

And overall I think it went quite well.  My Suave Sessions session was attended by a whopping ONE PERSON!  I seem to recall his name is Mark, and he runs the Ft. Worth DNUG, so kudos to him for picking a great session!  I know it wasn't sexy, but good session handling is something we should all be concerned about, certainly more so than getting an intro to DNN by the great Shaun Walker (who was presenting at the same time and whom I blame for stealing all my potential attendees).  The good news is that it's recorded and Wrox will be hosting it on their web site, so all of you folks who made the unfortunate decision not to attend can still get the session.  :)

Download the dotNetTemplar Session Management Module (for the Suave Sessions Session) - Even if you didn't see the session, you can start adding good session handling to your pages right away.  There's demo web project there to show how to use it.  If you want the demos from the presentation, let me know.

The EntLib session didn't go quite so well.  Apparently, I should really check to ensure my old demos work before the day of when I give a repeat session, he thought, embarrassed.  So I apologize again to all the troopers who toughed out the session with no running demos.  Thankfully, the core concepts could still be expressed; it just wasn't as fun as it could be.

Download the ELMAH EntLib Exception Handler/Logger - This can be used to both specify ELMAH as a custom EntLib exception handler and use EntLib for your db access in ELMAH.

To use it, configure ELMAH as usual.  If you want to use the EntLib logger, use GotDotNet.Elmah.EntLibErrorLog as the error log type instead of the standard SQL one. 

To use the custom exception handler in EntLib, you just need to choose it in the EntLib GUI by loading the ELMAH DLL and picking the GotDotNet.Elmah.ElmahEntLibExceptionHandler as the handler type.  It should look something like this in the standard config:

<add type="System.Exception, mscorlib, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089"
  postHandlingAction="None" name="Exception">
add type="GotDotNet.Elmah.ElmahEntLibExceptionHandler, GotDotNet.Elmah, Version=2.0.50727.42, Culture=neutral, PublicKeyToken=58d6fbf09c89f721" name="Elmah EntLib Exception Handler" />

The public key token will differ, though.  I just reconditioned this for public use real quick like, so let me know if you have any issues.

Download the Slides From Both Presentations - In case you didn't get the DVD.

Other than that, I have to give some big kudos to David Walker and his team for putting the conference together.  I've spoken at a number of code camp activities, and this was definitely one of the best organized and professionally done.  I can't help but think that their not shunning sponsors (like Infragistics) helped in making it better.  While I appreciate the academic ideal of trying to keep the code camp focused on devs sharing with devs, I think it is perhaps not in the best interests of anyone to shun sponsorship.  The vendors who sponsor conferences like that have tools that are supposed to make devs lives better, so in my opinion, it only makes sense to welcome them in as long as it is done tastefully.

And no, I didn't just start thinking this now that I'm working for a vendor; you can ask Joe Healy--I was pushing for sponsors when I was helping organize the Tampa code camp.  After all, it's not like Microsoft's stuff is free, and if the conference is about using Microsoft's technologies, why limit the vendor sponsors and topics to Microsoft?  Microsoft does a lot to make software development better, and we all welcome that.  I'm just suggesting the same thinking be extended to other companies who do the same thing.

Anyways, I didn't intend to rant about that really; I mainly wanted to say that David et al did a great job.  It was good to visit my hometown again, and while I didn't make it out to Ron's Chli & Hamburgers Too for that sausage chili cheeseburger I've been missing, I still thoroughly enjoyed the visit.  Tulsa certainly has been growing its dev community, and I hope they continue to do so.

That's it.  Hope everyone's having a great day!  Sorry bout the delay in getting this up.

Tuesday, October 17, 2006 3:55:26 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, September 30, 2006

A while back, I decided I needed to add browser-specific capabilities to my web application.  While there are those who advocate using capability testing rather than browser sniffing, there is at least one good reason to prefer sniffing.  That is that you want to be sure your site works as well as possible in all browsers but you want to take advantage of capabilities only available in some. 

In itself, this is not a reason to prefer sniffing; the key, however, is that you "want to be sure," which means testing; otherwise, your stuff may or may not work, which isn't very reassuring.  If you don't have the resources to do testing in all target browsers or the time to develop Javascript workarounds based strictly on specific capability detection, then sniffing is a good alternative because it allows you to only use "advanced" functionality in the browsers that you have tested and fall back to standard functionality for the rest.  This of course assumes you have architected your stuff in such a way as to make downgrading possible and still offer fairly equivalent services in a less rich presentation.  That in itself can be challenging and is far too involved and a bit off topic for this post.

So let's just assume you can fall back.  The next question is where you do the downgrading.  You can do it in Javascript, which if you only want to alter some functionality on the client side is fine, but if you want to, say, avoid Javascript altogether or emit significantly different script based on browser, the choice is to detect on the server and act appropriately.

Thankfully, most web server technologies support browser sniffing, and ASP.NET has expanded on and improved on this with their control adapters in 2.0.  But you can still use the old browser capabilities approach.  To do this in 2.0, you simply add the special App_Browsers folder to your web site or project (if you're using WAP).  In there you just add a file with the .browser extension, and you can put in your own custom browser capabilities there.  Here's an example:


browser refID="MozillaFirefox">
capability name="supportBubblePopup" value="true" />
capability name="supportAjaxNavigation" value="true" />
browser refID="IE6to9">
capability name="supportBubblePopup" value="true" />
capability name="supportAjaxNavigation" value="true" />

That's it, if all you want to do is extend the existing browser definitions.  If you want to define new ones or to find out more about the browser schema, you can consult the MSDN docs.  Using refID just lets you reference an existing definition and extend it.  You can view existing definitions that ship with .NET in the Framework CONFIG\Browsers directory (e.g., C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\Browsers), but be sure not to modify those directly to avoid your customizations being overwritten with later patches.

Note: You might be tempted to set a default value using refID="Default" as the docs suggest, but I've confirmed that there is a bug that causes the default to actually overwrite the more specific settings.  Microsoft tells me that they have scheduled a fix for this bug and that it will be released with the next Service Pack, but if you need it sooner, you can create a support incident and get a hotfix.  So the workaround is to not use Default and have your code check against null to determine default.  It's not the nicest approach, especially when you're using a Boolean value that would be better to just parse to bool, but it's not a travesty either.

You can then test for the capability in your code like so:


.Page.Request.Browser["supportAjaxNavigation"] == "true"

and do your downgrading if need be.  Of course, if you have some serious alternative rendering that needs to occur, you should consider using control adapters (especially the PageAdapter) to avoid complicating code with lots of conditional statements.


Saturday, September 30, 2006 2:30:26 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, September 15, 2006

Hi all, I just wanted to spread the word about the Tulsa TechFest next month.  As some of you know, I originally hail from Tulsa, OK, and I'm glad to be going back to my home town for this conference.  I'll be doing one session on EntLib for ASP.NET (modified version of my TechEd talk) and one on professional session handling (talking about things like HTTP modules, handlers, custom controls, etc. to gracefully handle sessions in ASP.NET). 

Of course, I'm just one of many speakers who'll be presenting on a large variety of topics, not just .NET.  They'll also have vendors with lots of goodies--I know Infragistics has some neat giveaways planned.  So if you're in the region, you should definitely check it out.  It looks like it'll be the best tech event that the heartland has seen.  Kudos to David Walker and the other organizers.

Friday, September 15, 2006 12:09:19 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, September 6, 2006

I just want to spread the word about a little utiltiy on gotdotnet that generates a strongly-typed profile for WAPs.  It's not the easiest thing to come across:


Note that the profile goo in 2.0 should just work, even with WAPs.  This just gives you a better design-time experience.

Wednesday, September 6, 2006 11:04:03 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, August 23, 2006

Everybody who has done any cross-browser web development is aware of the many quirks of IE6, so it is good to read, as Scott points out, that the IE team is addressing many of them with IE7.  While it isn't 100% yet, I've noticed that more often than not, if you get it right in Firefox, it looks right in IE7 and vice-versa.  That certainly cannot be said of IE6.

And on that note, I'd like to draw more attention to the IE web developer toolbar, which is mentioned in the IE team's blog.  Those who use Aardvark in Mozilla should definitely give this add-in a whirl.  It's not the same, but it does offer many similar features and some that Aardvark doesn't.  It helps take the guesswork out of troubleshooting layout and styling issues.

Wednesday, August 23, 2006 11:43:45 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, August 18, 2006

Here's a quick tip for something pretty neat in ASP.NET 2.0.  You can specify output cache profiles in the application configuration like so (this is under the system.web configuration section):

<outputCache enableOutputCache="true" />
add name="StandardPages" duration="300" varyByCustom="browser;culture" />

Then in your Global.asax code, add the following handler:

public override sealed string GetVaryByCustomString(HttpContext context, string custom)
string[] variances = custom.Split(';');
StringBuilder response = new System.Text.StringBuilder();
  foreach (string variance in variances)
switch (variance)
case "browser":
      case "culture":
return response.ToString();

Now, on any pages you want to be cached like this, you can just add the output cache directive like so:

<%@ OutputCache CacheProfile="StandardPages" %>

Of course, you can add other profiles for pages that, say, vary by parameters, controls, and the like, but this makes it easy to control the caching of all of a kind of a page via the web.config and also shows how you might set up a profile that varies by browser and culture.  And with an implementation of GetVaryByCustom like this, you can add your own variances and mix and match them in your profiles as desired.  It makes for a pretty flexible caching system.  For instance, you could add a check for authentication and, if authenticated, effectively turn off caching by appending a user ID or name and the current date and time (DateTime.Now.ToString()).  That way pages would be cached for anonymous visitors but for authenticated users, where the content is more dynamic, you might not want to cache.

Friday, August 18, 2006 4:54:02 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, August 1, 2006

I was just reminded via email today that I never came through on my intention to post something about my Oracle ELMAH provider.

There's not a lot to it, and if you want to understand it, just look at the ELMAH docs for how to write a provider.  There are some SQL files in the project that you'll need to run on your Oracle db.  Alternatively, there is a CreateElmahTable static method you can call from code to automate setting the table up.

Note that in addition to your standard connection string, there is a schema attribute you need to set in your ELMAH config to tell Oracle what schema to use for the ELMAH stuff.  Other than that, it should be plug-n-play just like ELMAH.  Enjoy!

Without further ado: Oracle ELMAH Provider (15kb)


Tuesday, August 1, 2006 11:31:30 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, July 26, 2006

Okay, so I'm a little late to this bandwagon, but on an email list I'm on, Michael Campbell alluded to Robert McLaws' shell extension idea to run the ASP.NET web development server for any folder.  Then, in a comment on that blog, Chris Frazier provides the code for a console application that overcomes some of the limitations that Robert's idea had and adds the nice feature of opening your default browser to the new root.

This is all fine and dandy, but where's the dang EXE?!  So I took Chris' code, incorporated Daniel Fisher's suggestion for getting the path to the web dev server.  In fact, I took it a step further and created a simple installer so taking advantage of this neat idea is as simple as running an installer.  So without further ado:

OpenCassini.msi (355kb) <-- This will do it all for you, including making it easy to remove via Add/Remove Programs

OpenCassini.zip (11kb) <-- You'll have to manually place the files and modify the .reg file to get it going.

I hope others find this useful and maybe a bit easier than setting all this up on your own.  Also, I'll be happy to share the project with anyone who cares, but there's not much to it beyond what's outlined in Robert's post.

UPDATE: I just found the post that Robert alluded to (too bad it wasn't linked from the original).  Unfortunately, his link is giving me a 404, so maybe my time wasn't totally wasted after all. :)

Wednesday, July 26, 2006 4:48:28 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, July 20, 2006
I've recently been informed that "the .NET Framework groups are offering another series of Live Meeting presentations called “Live from Redmond”. These talks are given by product team members, so it’s content directly from the program managers and developers on the team. The feedback from the first series that was done in partnership with INETA was overwhelmingly positive so Microsoft has decided to offer another set of talks."  Looking over the list, it looks like there's a lot of good stuff, so I thought I'd pass 'em along.

Client Talks




Registration URL


Smart Client: Offline Data Synchronization and Caching for Smart Clients

Steve Lasker

Click here


Windows Forms: An Overview of Windows Forms in Microsoft Visual Studio 2005

Saurabh Pant

Click here


Visual Studio: Developing Local and Mobile Data Solutions with SQL Server Everywhere

Steve Lasker

Click here


(WinFX) Windows Forms: How to Leverage Windows Forms and Windows Presentation Foundation in a Single Hybrid Application

Scott Morrison

Click here


Windows Forms: Solutions to the Most Common Windows Forms Development Challenges

Scott Morrison

Click here

Web Talks




Registration URL


ASP.NET: An Overview of ASP.NET and Windows Workflow Foundation Integration

Kashif Alam

Click here


ASP.NET: Building Real-World Web Application UI with Master Pages, Themes and Site Navigation

Pete LePage

Click here


ASP.NET: Creating Web Applications Using Visual Studio 2005 Team System

Jeff King

Click here


ASP.NET Atlas: A Developers Introduction to Microsoft Atlas

Joe Stagner

Click here


Best Practices and Techniques for Migration Visual Studio 2003 Web Projects to Visual Studio 2005

Omar Khan

Click here


ASP.NET: An ASP.NET Developer’s Look at Using RSS

Joe Stagner

Click here


ASP.NET: Under the Covers - Creating High-Availability, Scalable Web Applications

Stefan Schackow

Click here


ASP.NET: Using User, Roles, and Profile in ASP.NET 2.0

Joe Stagner

Click here


ASP.NET: Comparing PHP and ASP.net

Joe Stagner

Click here


ASP.NET: Security Tips & Tricks for ASP.NET Developers

Joe Stagner

Click here

Commerce Server Talks




Registration URL


Multi-Channel, Connected Commerce (BTS/CS integration)

Caesar Samsi

Click here


Commerce Server 2007 Overview

Mark Townsend

Click here


Commerce Server 2007 Architectural Deep-Dive

David Messner

Click here

.NET Compact Framework Talks




Registration URL


.NET Compact Framework 2.0: Optimizing for Performance

Ryan Chapman

Click here

Thursday, July 20, 2006 8:49:01 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, July 8, 2006

Well, I've finally settled on the software I'm going to use to write my blogs as well as read them.  I'm pretty picky about UI these days, and most of the software out there is just not that great when it comes to that.  But of course, I also need it to integrate and minimize the time it takes to set things up and the time I have to spend jacking with it on a regular basis. 

For authoring, I've decided to go with WB Editor 2.5.1 by Yiyi Sun.  I like the UI.  It currently uses the webby L&F, which when done right has a pleasant, light feel to it.  One thing that immediately strikes me as nice is that when I save a post for the second time, unlike BlogJet, it just saves to the same file I saved before and doesn't prompt me to pick a new file and then, when I select the same file, ask me if it's okay to overwrite it.  That really bugged me about BlogJet.  With WB Editor 2.5.1, CTRL-S works just like you'd hope, although it does pop up a notification saying it was saved, which is a bit annoying but can be dismissed with a spacebar slap.  I'd prefer the notification be in the status bar, but it's still much better than BlogJet in terms of saving drafts.

Post Authoring 
Post Authoring with WB Editor 2.5.1

Note that the color is green; it comes with three theme (skin) options: Blue (default), Green, and Pink.  I've always had a penchant for green.  Note also that the coloring of the post itself is like my dotNetTemplar blog; you can set this up using the options by specifying styles.  It's kind of nice so that you get a better feel for what it looks like, but it would be helpful to 1) allow for a stylesheet per blog and 2) encapsulate the entire post in a div to better capture the L&F of a single entry on a blog site (not sure how this would work in the editor, though).

I also like how ridiculously easy it is to insert images and screen shots.  When you click the insert/upload image icon, it has a friendly dialog that lets you pick the image or even paste from the clipboard.  It offers the option to automatically create a thumbnail and upload them both either via FTP or to Flickr.  I haven't tried the Flickr option, but it works great with FTP.

Adding Images
Adding Images with WB Editor 2.5.1

The HTML itself is clean, too, and it has a nifty little snippet insert drop-down for common stuff.  This is important to me because I don't want my editor using any markup--I want to leave it to my style sheets.  And it seems to play well with that.  It also highlights nicely, and the highlighting colors are personalizable.

HTML Editor
HTML Editing with WB Editor 2.5.1

Being a sucker for good UI, I enjoy the main screen that shows your registered blogs.  Yiyi has gone to the trouble to get images for the major blog engines (needs to update .Text to CS), so you get that along with a screen shot of your blog, the URL, and the categories.  And yes, you can of course cross post to multiple blogs, which is one reason to use an editor like this.

 WB Editor Home
WB Editor 2.5.1 Home

One of the really nice things about WB Editor from a .NET developer's perspective is that it has a plug-in architecture (currently running on .NET 1.1). 

WB Editor 2.5.1 Plugins

An important plug-in for devs is a code highlighter.  It may not be the nicest formatting, but it works.  If you don't like it, you could easily write a plug-in to use a formatter that you do like.

public class NavigationRoot
    NavigationLinkCollection items = 
        new NavigationLinkCollection();
    public NavigationLinkCollection Items 
            return items; 
            items = value; 

Another feature that I like about WB Editor is its roadmap, which promises to stay on top of the latest technologies from Microsoft, such as 2.0 and ClickOnce (coming in the next version) and ultimately .NET Framework 3.  It's a project that I could get excited about working on, and as you can see from the blog, it is actually being worked on.  Of course, it has other features that you can read about in its features list; I'm just highlighting the ones I think are cool.

So in short, it has everything that I'm looking for in a rich-client blog editor, and I'd recommend it over the much lauded BlogJet.  It is also competitive in pricing, currently at $19.99, which for a great piece of software like this is outstanding.

Now, I did mention at the beginning that I'd also settled on an RSS Reader.  I looked at a few, RSS Bandit, FeedDemon, Windows Live, Awasu, and probably a few others that don't readily come to mind.  My issue with all of these is the amount of work involved in setting them up.  It's not that they're particularly troublesome if you can live with a straight list of blogs from your OPML file, but if you like to categorize like I do, then it becomes troublesome, especially when you use multiple machines with multiple OSes on them.  Having to repeatedly setup my subscriptions kills me, and it's one reason I have always avoided using newsgroups.

Ideally, I'd like to just set them up once, and be able to read them either online or in a rich client, and have both of those stay in sync.  The only such RSS reader I ran across that met the bill was NewsGator, and in particular, their Inbox product that integrates with Outlook.  I might have gone with their FeedDemon product, except I am in fact one of those users that almost always has Outlook open, and I figure why have another app that is always running.  Also, I bought Newsgator way back in '04 when it first came out, so having an already-purchased license (with a free upgrade to the latest version) helped me decide.  Naturally, I had long since lost my license info, but they have a nifty license retrieval mechanism, so it was painless to get it going. 

The feature I most like, in case I wasn't already clear, is that they integrate and synchronize with their online reader, so I can have the best of both worlds, and when I want to set the rich client up, I can just grab the stuff from my already setup online source.  I can make new subscriptions and reorganize them on either the rich client or web, and it will keep them in sync.  It's the best of Plaxo for RSS.  Ah, now this is software for the connected world.

So that's about it.  I just thought I'd pass along my findings to you in case you've found yourself in a similar predicament.  I'm not trying to convince you to change if you're already happy with your setup, but if you aren't happy, consider these two products for the total blog/RSS reading and authoring solution.  I hope it helps!

Saturday, July 8, 2006 1:45:13 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, July 1, 2006

This is a repost.  The new blog authoring software I tried tonight overwrote this post instead of posting a new one.  I'll be reporting that bug. :)


For some, this may be old news, but I was just visiting again today, and I thought this is something that more people should know about.  So in case you haven't heard, the ASP.NET teams have put up a little section on asp.net to host side projects that they're working on; they call it the sand box.  Right now, they have 10 projects up there, including the famed "Atlas."

There are a number of other tantalizing tidbits that you might find interesting.  I just downloaded and installed the CSS Properties Window, which is a pretty neat way to edit your styles.  It will let you see the styles applied to a particular element while in design view and let you modify them, even ones in a linked style sheet, even using themes.

One they just recently released is this thing called the Blinq Prototype, which as I understand it is a tool that will generate an ASP.NET application using DLinq (ORM paradigm) based on a database.  Now, I'm a strong advocate of object-oriented and domain-driven design, but if you need a good starting place for an application that is based on an existing database schema that uses objects (not data sets) and integrated language query (which is totally awesome!), this promises to be a RAD tool (in both senses).

Yet another nice tool is the table profile provider.  The out-of-the-box profile provider in ASP.NET stores profiles data as a blob-like manner; this tool enables you to store the profile properties separately in the database as distinct columns.  I don't know about you, but that's how I prefer it.  It's always nice when you get free code done pretty much the way you want it.

One tool there that I find absolutely indispensible is the Web Application Projects.  That one's actually a tad more official than some of the others as it is a released add-on, but despite its official suit and tie status, it's still a really cool tool.  I find that I pretty much want to do all my ASP.NET apps as WAPs, maybe because it is more familiar from the 1.x days, but mostly because most of the apps I work on are team projects, and WAP plays much better with VSS, in my experience, than the 2.0 web site projects.

So the sand box is definitely a spot you should keep your eye on for new, cool stuff that comes out of band from the regular release cycles from Microsoft.  As far as I know, there is not currently an RSS feed for the sand box, but if you watch Scott Guthrie's blog, he's usually good about talking up the stuff they put out there.

Saturday, July 1, 2006 9:44:01 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, June 22, 2006
Come see .NET guru Bill Wolff tonight as he presents on SQL Reporting Services for the central New Jersey user group!

6:15 - 6:30pm - Pizza
6:30 - 6:45pm - Intro, Announcements
6:45 - 8:15pm - Main Speaker
8:15 - 8:30pm - Raffle

For Directions

Check out NJ.NET for more info and to sign up for future meeting notices.

Spread the word!  I'll see you tonight!
Thursday, June 22, 2006 10:15:24 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, June 14, 2006

If you're reading this and you attended my session on Monday morning at 9a but haven't yet filled out an evaluation, please do so.  I've been told the room seats over 800 and it was packed, but only 208 thus far have submitted evals.  I'd really like to know what EVERYONE thought, not just those few who've filled it out thus far.  It only takes a minute, and you get a chance to win an XBox if you do it sooner rather than later. 

Info again: 6/12/2006 - 9:00-10:15, WEB301 - Accelerating Web Development with Enterprise Library.

Just go to: http://msteched.com, log in, and go to fill out evals for breakouts (menu on left).

And remember, be honest but kind!  :-p

Wednesday, June 14, 2006 5:32:30 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, June 5, 2006

As most of you know who follow my blog at all, I recently joined Infragistics.  Well, I finally got around to getting my company blog set up, so if you're curious or interested, feel free to check it out and maybe subscribe.  While you're there, if you are a customer or potential customer, you might want to look around at the other blogs and maybe subscribe to some of them to stay on top of Infragistics stuff.

Monday, June 5, 2006 11:16:05 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, May 9, 2006

Just doing my part to spread the good word:


Tuesday, May 9, 2006 4:59:25 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, May 3, 2006

Just thought I'd stick these out there for anyone else who might run across them.  Those of us reared under the friendly wing of SQL Server are in for regular surprises when interacting with Oracle...  But hey, what doesn't drive you mad makes you stronger, right?

1. Using a DDL statement inside a transaction automatically commits any outstanding DML statements.  I ran into this the other day when I was trying to have a transaction that added a row to a table and added a trigger (dependent on that row) to another table.  (This is actually part of my implementation of an OracleCacheDependency, which I intend to share in an article at some point.)  If you stepped through the code, everything appeared to function as expected, the exception would be thrown on the add trigger statement, RollBack would be called on the OracleTransaction, and... the new row would remain in the database.

It was actually driving me buggy.  I was beginning to wonder if Oracle supported ADO.NET transactions at all because every example (all two of them) that I could find looked just like my implementation.  I even tried both the System.Data.OracleClient and the Oracle.DataAccess.Client, which, by the way, require different implementations as the Transaction property on the Oracle-provided provider is read only (you have to create the commands from the connection after starting the transaction, which is, umm, inconvenient in some scenarios).

So I was pulling my hair out, about to give up, when I ran across a single line in the help docs that says "The execution of a DDL statement in the context of a transaction is not recommended since it results in an implicit commit that is not reflected in the state of the OracleTransaction object."

Okay, I guess I'm just spoiled by Microsoft (yes, I am), but I would expect an EXCEPTION to be thrown if I try to do this and not have the code happily carry on as if everything was hunky dory.  You'd think that a database that is picky enough to be case sensitive might be picky enough to not let you accidentally commit transactions.  And that leads in my #2 gotcha for the day.

2. Oracle is case sensitive when comparing strings.  Let me say that again (so I'll remember it).  Oracle is case sensitive when comparing strings.  Now this point, in itself, is not particularly gotchaful; however, when coupled with a red herring bug report, it can really sneak up on ya and bite ya in the booty.  This is just one of those things that you need to keep in the upper buffers when debugging an app with Oracle.

3. (This one is just for good measure; I ran into it a while back.)  Oracle 10 no longer uses the old Oracle names resolution service.  This means that if you try to use the nifty Visual Studio Add-in and your organization is still using the old Oracle names resolution, you'll have to create manual entries in your tnsnames.ora file(s) just so that you can connect.  Even when you do this, it has to be just so or it won't work. 

I've had it where you can connect in the net manager but can't connect in the Oracle Explorer using the connections, which is sees and reads from the tnsnames file.  In particular, if I removed the DNS suffix from the name of the connection (to make it pretty), it wouldn't work.  It'd see the connection but not be able to connect.

4. (Another oldie, but importantie.)  Oracle, as of now, does not support ADO.NET 2 System.Transactions at all, if you use the Oracle-provided provider.  From what I could tell, although I wasn't able to test successfully, the Microsoft-provided one looks like it should, at least it should use DTC, but the jury is out.  Feel free to post if you've gotten it to work.

5. There is no ELMAH provider for Oracle.  I implemented one, though, and will be sharing in an article at some point.  Feel free to email me for it in the meantime.

6. There is no Oracle cache dependency.  See #5.

7. There is no Oracle roles, membership, etc. provider.  Sorry, I've not done that yet.

There are other bumps and bruises that you will get when dealing with Oracle if your main experience is SQL Server.  Many of them are just due to lack of familiarity, but there are some issues that I think truly make it a less desirable environment to work with.  So I thought I'd just share a few of them here for others who might find themselves in similar binds and need the help, which is so hard to find for Oracle.

Wednesday, May 3, 2006 2:34:41 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, April 29, 2006

I just updated this site to the latest version of dasBlog.  Many, many thanks to Scott for helping me out with getting it (given that I am a total noob to CVS and, apparently, picked a bad time to start since SF was having issues).  Most notably (that I know of), this version incorporates using Feedburner, which I guess is the latest and greatest for distributing your feed and lowering bandwidth usage, though I'm sure there are some other goodies in there.

Anyhoo, let me know if you suddenly start running into any problems with my blog.  Have a good un!

Saturday, April 29, 2006 2:19:18 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, April 27, 2006

I decided to try something new in ASP.NET 2.0 based on our needs on a current project.  To do this, I followed the tip that K. Scott Allen shares in his blog.  The difference in my case is that I thought I'd do this and make the user control in the App_Code be the base control for a handful of others.  The point here is to achieve visual polymorphism.  Put another way, I want to load up the control differently based on the sub classes rather than, say, having a big switch statement.  This is just good OOD.

The problem is that if you just set a user control in the App_Code directory as a base for other user controls, you will most likely see the following exception.  I was able to consistently reproduce it.  When ASP.NET constructs your derived user control, .NET, as usual, calls the base constructors as well.  When the base constructor is called like this (for reasons beyond my ken), I see this error:

 System.Web.HttpException: An error occurred while try to load the string resources (FindResource failed with error -2147023083).

Looking at what is actually happening (in the call stack), the error appears to be in a call that the parsed constructor makes to System.Web.StringResourceManager.ReadSafeStringResource(Type t).  If you Google like I did, you probably won't find any help (except this blog now, of course).  So on a hunch, I called the LoadControl overload like Scott Allen suggests in his piece, and it loaded fine.  On a further hunch, I then tried to use the derived control again, and voila, it worked fine.

So, since I don't have time to open a case with Microsoft, I just created that as a work around.  I have the application call LoadControl once on the base control so that ASP.NET will properly set it up for use, and then I can use it as a base.  You could do this (presumably) in Global.asax, but I just put this in the page that uses the control(s) in question.

static bool _baseUCLoaded = false;

protected override void OnInit(EventArgs e)
  if (!_baseUCLoaded)
    ASP.MyUserControlBase thing = (ASP.MyUserControlBase)this.LoadControl(
      typeof(ASP.MyUserControlBase), null);
    _baseUCLoaded = true;

And it appears to work.  Maybe someone will enlighten me on this, but I have a hunch that it is just an unexpected scenario (a hack) that wasn't covered by testing.  In any case, it's pretty neat that it works.

Thursday, April 27, 2006 10:41:34 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, April 24, 2006

Not long ago, I polled subscribers as to what they're interested in.  There seemed to be a fairly even divide between what I'll roughly call Technical posts and Non-Technical posts.  In fact, my goal with this blog is to be a blend of those two general categories.  At the same time, as much as it hurts to admit it, I know that some folks really don't care about my opinions on non-technical matters.  So it struck me (some time ago, actually; I've just been lazy) to create two general categories using the creative taxonomy of Technical and Non-Technical. 

Why?  This is because dasBlog (and most other blog systems, I imagine) allow you to subscribe to category-based RSS feeds as well as view posts by category.  So from this day forward, in addition to the more specific categories, I'll be marking all posts as either Technical or Non-Technical.  If all you care about is one or the other, you can just subscribe to one or the other and never be bothered with the stuff you don't care about.

You can view/subscribe to the feeds using the feed icon next to each category in the list (of categories).  Here are direct links as well:



I hope this helps!

Monday, April 24, 2006 10:28:33 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 

In a recent post, I mentioned the acronym OPC, meaning "Other People's Code."  Somehow I doubt I'm the first person to use the acronym, so I don't intend to claim it as my own.  I can't say I've seen it before, but it seems so obvious that it should be one because OPC is so prevalent and we should all be talking about OPC much more than we do.  In an industry that arguably values reuse over every other virtue, you'd think that OPC would have long been canonized.

Yet it seems to me that when most people speak of reuse, they mean Their Own Code (TOC, I love overloading acronyms!) or, from their perspective, My Own Code (MOC).  In essence, they want other people to reuse their code, but there ain't no chance in heck that they're going to use OPC as a means to achieve the ultimate goal.  I want MOC to be reusable.  How can I impress my friends by writing code that can be reused by as many other people as possible?  This is something I think most of us that strive to be great at software think at one point or another, perhaps not in so many words, but ultimately, there is a sense of great pride when you polish off that last speck on your chrome-plated masterpiece, showing it to your buddies or the world in general and saying "that's MOC." 

The funny thing is that more often than not, the really ardent software folks among us, and even the less ardent, have a predilection for the NIH syndrome.  It's because we're all so damned smart, right?  Surely, those other folks at NIH Co. couldn't possibly have done it as well as I could have!?  Of course, we've got all the rationalizations lined up for when the business folks ask:

1) "I can't support that because I don't know it--I need the source code."
2) "You know, it won't meet our needs just right, not like I could do it for you custom."
3) "How much?  Geez.  I could write that in a day!"
4) "It's not using X, which you know is our preferred technology now."
5) "Did they promise to come work here if they dissolve the company?  I mean, you're just gambling on them."

And the list goes on.  We've probably all done it; I know I have.  Why?  Because, as one developer friend once put it (paraphrased): "I love to invent things.  Software is an industry where you get to invent stuff all the time."  In other words, we're creative, smart people who don't feel that we're adequately getting to express our own unique intelligence unless we write the code ourselves.

And now we finally come to what prompted this post.  I recently looked over an article by Joshua Greenberg, Ph.D. on MSDN called "Building a Rule Engine with SQL Server."  I'm not going to comment on the quality of the solution offered because I hardly think I am qualified to do so.  What I was completely flabbergasted by is the total omission of the rules engine being built into Windows Workflow Foundation.  Surely someone who has put that much thought into the theory behind rules engines, which, as is mentioned in his conclusion, are probably best known in workflow systems, would be aware of WF's own?  Surely one of the editors at MSDN Mag, which has done numerous articles on WF, including one on the engine itself published in the same month, would think it worth noting and perhaps comparing and contrasting the approaches?

Now, I don't want to draw too much negative attention to the article or Mr. Greenberg.  He and the editors are no more guilty of ignoring OPC than most of us are.  It is just a prime example of what we see over and over again in our industry.  On the one hand, we glorify reuse as the Supreme Good, but then we turn around and when reusable code (a WinFX library, no less!) is staring us in the face, an SEP field envelops reuse, enabling us to conveniently ignore OPC and start down the joyous adventure of reinventing the wheel.

This has got to stop, folks.  I'm not saying that this ignorance of OPC is the primary cause of the problems in our industry (I happen to think it is only part of the greater problem of techies not getting the needs of business and being smart enough to hide it).  But it is certainly one that rears its ugly head on a regular basis, as we guiltily slap each others' backs in our NIHA (NIH Anonymous) groups.  We have a responsibility to those who are paying us and a greater responsibility to the advancement of our industry (and ultimately the human race) to stop reinventing the wheel and start actually reusing OPC.  I'm not saying there is never a justification for custom code (God forbid!), but that custom code needs to be code that addresses something that truly cannot be adequately addressed by OPC. 

There will always be plenty of interesting problems to solve, which give way to creative and interesting solutions.  Just imagine if all this brainpower that goes into re-solving the same problems over and over again were to go into solving new problems.  Where would we be now?  Now that's an interesting possibility to ponder.

Monday, April 24, 2006 10:21:02 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [2]  | 
# Tuesday, April 18, 2006

I just ran across a new feature of .NET 2.0 that's pretty nifty if you've ever had a need for it.  They have a new attribute, InternalsVisibleToAttribute, that allows you to tell an assembly who its friends are.  This feature, as you might imagine, is dubbed friend assemblies, and it means what it sounds like--friend assemblies can access internal code in the assembly that the attribute is applied to.  This is particularly useful in two scenarios I've run into:

1) You want to easily unit test internals.  Yes, there is some disagreement as to whether that's the right way to test things, but at least you can do it if you need to (and in my experience, you occasionally do).

2) You've neatly packaged code in separate assemblies that are related and need internal access but make sense to be packaged separately.

It seems like kind of a hack, but I think it is a nice one.

Tuesday, April 18, 2006 10:25:35 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, April 17, 2006

I've been running XP 64 on my new box for a few weeks now, but I've managed to get by thus far without tweaking IIS much.  I was pleasantly surprised when something wasn't working that required the ASP.NET process identity to have write access (dasBlog).  I immediately went to the dir and added ASPNET w/ modify perms on the dir and still got the permission denied error.  So I went back into IIS and lo and behold, it was running IIS 6.  Too cool!

Of course, you may be wondering how I managed to overlook this fact for so long.  It is because I just assumed that it was just running the IIS 6 Manager client.  I usually install that on my XP boxes because I like the updated interface, and it allows me to connect to 2003 IIS servers.  So it didn't phase me at all to see the IIS 6 client.  Somehow I managed to get by without noticing that it was in fact running IIS 6. 

So I just changed the user with write access to Network Service and voila!  Pretty snazzy.  The point is to let you know that if you want IIS 6 with XP, one option is to go out and buy 64 bit machine and run Windows XP 64 on it.  :)  I can tell you that it has a few quirks, but most of them you can work around.  I've not had to boot to my 32bit dual boot at all.  So if you're in the market for a new machine, you should definitely consider 64 bit.

Monday, April 17, 2006 2:44:37 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [2]  | 
# Thursday, April 13, 2006

I'm very happy to announce that I'll be joining Infragistics soon.  Officially, my first day will be May 15th; however, I'll be going to the Alabama Code Camp to represent them next weekend (4/22).  If you're in the Huntsville area, you should definitely check it out; there are tons of great speakers and sessions lined up.  (Mine's not up there yet as it is still undecided which of the ones I submitted I'll be doing.)

Anyhoo, I'll be working for Infragistics as their Codemunicator, a title that they let me coin because the position is kind of a blend of things.  Codemunicator is a portmanteau, as you might guess, from "code" and "communicator."  It sounds like it'll be a lot of fun; I'll get to do a number of things that I enjoy--writing, designing, coding, and even the occasional speaking from what I hear.  And I'll get to work with great guys like Jason Beres (noted author and INETA speaker), Devin Rader (also noted author and ASPInsider), and others whom I've had the pleasure to meet. 

Plus, some other really cool peeps are not far away, like DonXML (MVP and XML extraordinaire), Scott Watermasysk (Mr. .Text himself, ASPInsider, MVP, etc.), Doug Reilly (author, ASPInsider, MVP, etc.), Terri Morton (author, ASPInsider, MVP, etc.), DotNetDude (author, INETA speaker, MVP, etc., though I hear rumors of his not being long for the area), and I'm sure I'm not aware of or forgetting others and/or not getting all of the accolades right (that's my official apology if that's the case).  So all I'm saying is it's a really cool area for .NET experts and ubergeeks. :)  Hopefully we can all get together occasionally for dotNetMoots of some kind.

Of course, this change in employment constitutes a change in locale for me and my family.  We'll be moving from sunny Tampa, FL up to Princeton, NJ (right near East Windsor, home of Infragistics HQ).  I'm sure a lot of folks think such a move is crazy, but the wife and I are not especially keen on the six-month summers down here in Tampa.  We both grew up in cooler climes that have all four seasons, so we're actually looking forward to having them again.  That's not to say that the Tampa area doesn't have lots to recommend it, most notably family, friends, and mild winters, but we still feel this is the right move for us.

We've heard a lot of good stuff about the area we'll be in, both from folks who live there now and who lived there in the past.  Apparently, the whole "armpit of the US" epithet only applies to the Newark/Elizabeth area (in the NE near NYC), and having flown into and out of Newark and driven by Elizabeth, I can believe that.  (No offense to anyone who lives there and likes it!)  But central NJ is actually quite nice from what we saw when we toured the area a bit and from what we've heard.  It's about an hour by train from NYC and Philly, not far from some mountains in Pennsylvania, and not far from the beach and Atlantic City, so we're actually looking forward to it a lot.

All in all, we're pretty psyched about the move, and I'm especially juiced about going to work for a great commercial software company like Infragistics.  They still have openings, so if you think any of them sound interesting, let me know.  I'd love to have more good people come on to work with us.  If any geeks or ubergeeks live in the area and read my blog that I don't know about, give me a shout out.  I'll be helping Jason Beres et al pump up the NJDOTNET user group, so join and come if you're in the area.  You WILL join and come! <waves hand using Jedi mind trick>


Thursday, April 13, 2006 10:13:08 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [9]  | 
# Tuesday, April 11, 2006

At the recent Orlando CodeCamp, I did a presentation called (roughly) "Introduction to Generic Database Programming with ADO.NET 2."  Phwew.. gotta take a deep breath after that one.  So, the premise of the talk was to introduce folks to the features in ADO.NET 2.0 that make provider-agnostic (a.k.a., generic) database programming possible.  And I think that was accomplished in that it covered the System.Data.Common namespace and had an example that illustrated how to create connections using the DbProviderFactories class and the provider invariant name as well as how to retrieve metadata information using the GetSchema methods on DbConnection.

In my chapter for Professional ADO.NET 2, I created a very basic custom ADO.NET provider for Active Directory, which required me to implement most of those classes and provide the basic info from GetSchema.  So I was familiar with it from the theory side of things and thought it was pretty neat as an idea.  But I personally have not had the opportunity to really dig into doing it much myself; I prefer using an object-relational mapper when I can, and I've been fortunate enough to not be in too many situations where doing "real" generic db programming was necessary.  I also knew, in theory, that there were complications in creating database-agnostic code, but I didn't know just how unfinished it is.

Consider, for example, that Oracle returns results from stored procedures using an output cursor parameter instead of a regular result set; this can make it less than generic when you want to use sprocs.  And even something as simple as dynamic SQL command parameters is not fully addressed with the new ADO.NET 2 stuff.  It is this fact that prompted this blog entry.  I was trying to do something super simple--create a very focused test data generation tool that could use Oracle or SQL Server as its persistent data store. 

In particular, for the commands (trying to follow best practices), I was going to use ADO.NET parameters instead of string concatenation or substitution, and I recalled that one of the new standard schemas is a DataSourceInformation schema that specifies, among other things, a format string for parameter names.  In other words, as my friend Plip demonstrates on his blog, I should be able to use that value with String.Format in order to get a properly-formatted parameter name for my commands.

It turns out, though, that it just don't work, at least not in the RTM version.  (In Plip's defense, that post was made when Beta 1 was current.)  In the RTM, the SQL Server provider returns simply "{0}" as the parameter marker format string, which is, I'm sad to say, utterly useless.  It should return (in my humble opinion) "@{0}" to prepend the @ in front of the name as that's what SQL Server expects.  Looking at the Oracle provider, it correctly prepends the : using ":{0}" as the format string.  So, something that should be as simple as getting an appropriate parameter name is goofed up. 

Now maybe I'm missing something, but I know that folks like Frans Bouma, who have far more experience than I writing code to interface with multiple providers, seem to indicate that my impressions are not far off.  My own object-relational mapper completely abstracts the SQL itself such that providers have to supply SQL templates, so I'm not faced with writing generic SQL and can still take advantage of the abstractions provided by ADO.NET.

So I guess it really depends on what you're looking for when you say generic database programming.  For now, it seems only partially fulfilled, particularly since the queries themselves don't have sufficient standardized abstractions (that I'm aware of anyways).  I know there is a SQL standard, but as far as I can tell, it is fairly limited and doesn't cover simple things like (as Frans pointed out) getting an db-generated identity value back.

The good news is that there are good abstractions that can take care of a very large portion of the provider-specific work for us.  Obejct-relational mappers are one such example, and with the advent of LINQ and DLINQ, I hope that we'll find less and less need to actually write SQL ourselves and rely, rather, on these higher-level, object-oriented abstractions to hide the complexities of data persistence for multiple providers.  Generic database programming isn't a myth; it's just a legend, something based in truth but not a full reality.  What do you think?

Tuesday, April 11, 2006 8:26:01 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 

I just spent a few hours diagnosing what appears to be a bug in the new ListBindingHelper class used by, among other things, the Windows Forms DataGridView control.  If you call one of the GetListItemProperties methods, as the DGV does when automagically determining the columns based on your data source, it may ultimately call a helper method called GetListItemPropertiesByEnumerable.  This is a last ditch attempt to determine the properties based on the type of objects in your data source. 

Well, actually, it is the second choice; it will first look to see if your list class implements ITypedList and let it take over the work of getting the properties, but if your list class is one of the handy ones in the framework (an array, ArrayList, List<>, etc.), it will fall back on the GetListItemPropertiesByEnumerable method, assuming your list class implements IEnumerable, which most do (as an aside, it will then just get the properties on your list or, to be more precise, whatever the heck you passed into the method).

So the bug (or so I call it) is in that method.  I presume in an effort to be all high-performing and such, the developer wrote in a killer short-cut:

Type yourEnumerableListType = yourEnumerableList.GetType();
if (typeof(Array).IsAssignableFrom(yourEnumerableListType))
  return TypeDescriptor.GetProperties(yourEnumerableListType.GetElementType(),

Note that I took liberties of paraphrasing here, but if you know how ICustomTypeDescriptor works, you'll readily see the problem here.  You see, it works on instances, not types.  This means that your implementation of ICustomTypeDescriptor will never be called if you are binding an array, even if there are valid instances in the collection upon which it could be called.  I see this as a major bug, and I'm quite surprised it made it through QA.

You see, if your enumerable list class is not just a plain-Jane array, it will fall through that short-cut down to what it really should be doing, which is getting the first item from the enumerable list and calling TypeDescriptor.GetProperties (the object-based one), which will call your implementation of ICustomTypeDescriptor and allow you to substitute a property list of your choosing.

Now, there are certainly plenty of workarounds for this, and in fact, I wouldn't have run across it if it weren't for the fact that someone else wrote this method to return an array instead of (e.g., an generic List).  But that's not the point; the point is that it shouldn't be doing this.  If there are objects in the enumerable list, it should interrogate them, regardless of whether or not it is an array.

In any case, whether or not you agree with my classification of this as a glaring bug, I hope that maybe someone will benefit from the time it took to research this gotcha (because it most definitely is that).  The short answer, though not the ideal, is to just not bind to arrays and use either an ArrayList or generic list or collection or whatever.  And, by the way, if you're wondering how I figured all this out, there's a nifty little tool called .NET Reflector that provides many insights.  It's not as easy as debugging (because you can't actually step into the code), but if you're good at reading and following control flow, it can help you gain a much deeper insight into OPC (other people's code) when the docs just aren't sufficient.

Tuesday, April 11, 2006 7:00:02 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [1]  | 
# Saturday, April 8, 2006

One of the great Florida.NET guys, David Silverlight, has put together a pretty nifty community site called Community Credit.  The tag line is "we give stupid prizes to smart people."  The basic gist of the site is that you can enter your community activities and, depending on what they are, get a certain number of credits/points.  Every month, the top N community folks get awarded with stupid prizes.  So if you're doing dev community work, go sign up and start recording your points.  Not only will it help you track what you're doing, it will also let others know what you're up to and, hey, you might just win something.

Oh and, yeah, I know, it's been around for a few months; I've just been too lazy to blog about it until now.  So sue me! :)

Edit: I forgot to mention, you should also sign up for the newsletter.  David's got a pretty good sense of humor, and I think you'll enjoy it.

Saturday, April 8, 2006 1:40:32 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, April 6, 2006

This is for anyone who is "lucky" enough to have to use Oracle as a data source in .NET and wants to use the new features in the System.Transactions namespace (which is pretty cool, by the way).  In searching around for an answer to whether or not Oracle supports System.Transactions, I found that they do, but with a cost.  You see, if you use System.Transactions with Oracle (or any non-SQL Server 2005 transaction resource manager), all transactions will be coordinated through the Microsoft Distributed Transaction Coordinator (DTC).  This involves a fair amount of overhead in terms of processing and resources and can involve headaches when truly dealing with distributed transactions.

SQL Server 2005 takes advantage of one of the nifty features of System.Transactions, which is what they call Promotable Single Phase Enlistment (PSPE).  This means that by default, when you start a transaction using, say, TransactionScope, and the first data source in the transaction is SQL Server 2005, it will start out as a standard SQL Server transaction, meaning it would be equivalent to using SqlTransaction on a single connection.  However, if you add other data sources including (I presume) other connections to SQL Server 2005, it will promote that transaction to a distributed transaction managed by the DTC.

This is pretty cool because many of us use transactional programming against a single data source, so we can take advantage of TransactionScope and the so-called ambient transaction without incurring the overhead of DTC.  But unfortunately, as of writing, there is no such support for other transaction resource managers (such as the one included with the Oracle ADO.NET client).

My recommendation would be against using System.Transactions unless you are going to be having distributed transactions most of the time.  Hopefully Oracle will implement the PSPE for their ADO.NET provider, but in the meantime, it just isn't worth the overhead.

Thursday, April 6, 2006 1:41:04 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [3]  | 

I just ran into an interesting bug in the super simple role provider I wrote for a client.  If you see the following error:

Key cannot be null.
Parameter name: key


with a stack trace of:

System.Collections.Specialized.HybridDictionary.get_Item(Object key)
System.Web.Security.RolePrincipal.IsInRole(String role)

Chances are that your role provider is returning a null as one of the role names from the GetRolesForUser method.  In my case, my data source was storing null role name values, and my provider just passed up to the UI whatever roles the data source gave me.  To fix, I added checks to not store null roles for users (long story as to why it is possible to do that in my case).  So that's probably what you need to look for if you see this exception scenario.


Thursday, April 6, 2006 1:28:55 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [1]  | 
# Wednesday, April 5, 2006

I warned you about Scott Guthrie, didn't I?  Subscribe to his blog or else! :)

Here you go!

Wednesday, April 5, 2006 9:22:52 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, April 1, 2006

If anyone's like me and is used to using pubs for sample applications, you might find that you miss it when you install SQL Server 2005.  Now I'm sure there are more ways to go about getting it back, but for the heck of it, I did a local hard drive search for pubs, and look what it turned up.  Not only do I have a script to install pubs but also Northwind and others.  The directory on my machine is E:\Program Files\Microsoft.NET\SDK\v2.0 64bit\Samples\Setup, but I figure it'll be under the Samples\Setup of wherever you happen to have the 2.0 SDK installed.   Ahh.. pubs.. dear old friend... 

Saturday, April 1, 2006 4:27:49 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [2]  | 
# Friday, March 31, 2006

In time, I hope to be able to look back on this day and think wow, was I ever that ignant?  Something that has plagued me and many others in ASP.NET 1.x has been resolved (no pun intended) in 2.0, viz. a static framework method to resolve an application-relative URL into a server-relative URL.  This is one of those problems that you feel like there must be a solution for, but maybe you just could never find it, or maybe you just didn't take the time because you created a solution that worked well enough.

In 1.x, on virtually every application I wrote, I ended up creating some utility method that would essentially do what the ~/ would do in a user control, which is equivalent to calling the ResolveUrl method.  The main idea, of course, is that we need a URL that is valid, regardless of the context, regardless of whether or not the application is being run on a development machine in a virtual directory or on a production server off the root.  Or maybe we just wanted to make it easy to change the virtual directory name--you know how fickle those users can be when it comes to what they want to see in the address bar! :)

So what did you do in 1.x?  Specifically when you didn't have a readily-available control to call ResolveUrl on?  If you're anything like me, DotNetNuke, or sundry others, you probably made some utility function that would squish the application path in front of the URL using the Request.ApplicationPath, if you could, or if you were really knowledgeable, the HttpRuntime.AppDomainAppVirtualPath property.  (Shh, don't tell anyone.. apparently, I'm not that knowledgeable as I just had this pointed out to me by David Ebbo; I usually hacked that one as well, storing it in my Global class by ripping it off of HttpRequest or worse, specified it in the web.config... oog).

Well, even if you do get the application path, you still have to write a function to munge it with the relative URL to come up with what I call the server-relative URL (i.e., an URL that starts with /).  Good grief!  Couldn't they have a function to do this that is static (doesn't require a valid request context)!?

Never fear, in 2.0, we have a neat new utility class called VirtualPathUtility!  You can read through the docs to figure out all the neat-o features, but the only one I particularly care about is ToAbsolute.  This one is, as far as I can make out, the functional equivalent of ResolveUrl, so now I can resolve server-relative URLs from app-relative ones without needing a valid request context and without writing my own functoid for it.  Woohoo!  Note: I say "server-relative" because the URL is relative to the server root.  For some reason, the MS folks call it "Absolute."  To me, absolute would include the full URL, including server.  I'm sure they had a good reason for it...

So that's it.  No more messing about with all that garbage.  Just declare all of your URLs using ~/, and call VirtualPathUtility.ToAbsolute to get a URL that should be valid regardless of your deployment environment.  Too cool! 

Edit: Forgot to give credit to David Ebbo on the Web Platforms and Tools Team at Microsoft for pointing out this new utility class to me.  Thanks, David!

Friday, March 31, 2006 9:50:42 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [2]  | 
# Friday, March 10, 2006

asp.netPRO is doing their yearly survey to see who's the best of the best.  I hope you will consider voting for ASPAlliance.  We've been working to improve your experience over the last year, and our vision is to keep improving and providing high-quality content for Microsoft developers in the future.

Also, if you don't know whom to vote for in hosting, go for Server Intellect.  They do an awesome job of providing affordable, high-quality hosting and enabling you to take control.

Go vote!

Friday, March 10, 2006 6:18:18 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, February 17, 2006

Have you heard of the International Association of Software Architects?  If you’re a software architect, or even an aspiring one, you need to be aware of this inspiring organization.  While some architecture organizations focus on a top-down, global or vendor-based approach, the IASA focuses on all IT architects at every level, regardless of their vendor affiliations, starting at the local area.  To better serve this end in the central Florida area, Tom Fuller and I have started up the Tampa Bay chapter

The IASA’s sole aim is to provide value to each other and to make IT/software architecture a full-fledged profession with a significant knowledge base and quality controls.  Key goals of the IASA are:
   • To provide the latest news and articles in the architecture discipline.
   • To support the establishment of strong relationships among architects both as peers and as mentors.
   • To support and fulfill the needs for working groups as challenges in our industry call for them.
   • To provide both local and a global forum for debate of issues pertinent to the profession.
   • To enable each and every architect the ability to grow in the profession and to impact the software industry in positive ways.

If you want to know more about this organization, please visit the IASA Web site or contact Tom or me directly (or even comment on this blog).  To get involved and be aware of important announcements (such as meeting times) in the Tampa Bay and central Florida area, register on the site for the Tampa Bay chapter.   We look forward to seeing you there!

Friday, February 17, 2006 4:00:07 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, February 7, 2006

Check out my latest piece on ASPAlliance and let me know what you think!

Tuesday, February 7, 2006 9:00:23 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, January 26, 2006

In a comment on my post last April about SoCal's charging for a code camp-like event, Woody Pewitt, Microsoft Developer Evangelist for Southern California, acknowledges that the Florida developer community is the best in the world.

Thanks, Woody!

Thursday, January 26, 2006 8:47:32 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [1]  | 
# Friday, December 23, 2005

The latest issue of CoDe Magazine has an article called "I Object."  I wrote this piece quite some time ago as should be evident by the fact that I call the May/June issue "recent."  The content for this latest issue is not online yet but should be soon, I imagine (I just got my hard copy yesterday).  The reason I'm mentioning this is that I feel the need to acknowledge some recent advances made by Microsoft in the way of promoting object-oriented design.  Both of these were announced at PDC, after I wrote the article, and yes, I failed to revise it before publishing (my bad).

First, Microsoft announced the new Language Integrated Query (LINQ) technology.  I think this is an absolutely huge step forward in easing some key difficulties now present for OO development in .NET, as I previously discussed on this blog.  Whether or not this is a real innovation (I've heard something like it has been present in other languages/platforms), I give Microsoft big kudos for bringing it into the .NET family as only they could.

Second, Microsoft released the public preview of WinWF.  Just the other day, I posted an article discussing this technology and its importance.  While this is not directly an OO thing, it does (obviously) use OOD, and it adds a new facet to our development that is focused on processes.  In addition, its activity-centric architecture has a similar potential to OOD in that it lends itself to being highly composable and reusable.  Together with good OOD, this technology could have a dramatic impact on software development.  And I give Microsoft further kudos for being bold enough to bet on it; I think, for better or worse, that they are the only real singular force that has the power to shape our industry. 

I should also mention that their DSL tools and, in particular, the class designer are a step in the right direction to help make good OOD easier.  I failed to mention that in the CoDe article, and I should have.  The folks in the dev division at Microsoft are some of the brightest in the industry, and it's good to see that they're starting to focus more on OOD and other key aspects of development that can evolve business application development in a positive direction.

Friday, December 23, 2005 7:30:57 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [2]  | 
# Thursday, December 15, 2005

If you're interested in ASP.NET, IIS, and Visual Web Developer and you're not subscribed to Scott Guthrie's blog, you have a problem. :)  He's the Group Product Manager for the Web Platforms and Tools teams (I hope I got the title right) and all around nice guy.  His posts are always very insightful into either something about Microsoft's Web dev technology or their development processes.  Good stuff.

Anyways, today he posted a very handy code snippet that shows how to track shutdown events in ASP.NET.  I hear he got it from Thomas Lewis, famed ASP.NET evangelist (can't remember his exact title off hand), but wherever it came from, it's useful to help diagnose shutdown issues and see one example of just how well they've instrumented their products.

Thursday, December 15, 2005 9:37:20 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, December 13, 2005

The script below will grant execute on all stored procedures in the selected database to the specified role.  Just change it to use your database and, if desired, change the role name.  After that, just add users to that role.  You should be able to rerun this script as needed.  It was tested in 2005 but should work in 2000.

use [YourDatabase]

declare @sprocName sysname,
    @roleName sysname,
    @grantStatement nvarchar(4000)
select @roleName = N'db_exec_all_sprocs';

if not exists(select * from sys.database_principals
    WHERE name = @roleName AND type = 'R')
        exec sp_addrole @roleName;

declare sprocs cursor local for
    SELECT [name] FROM sys.objects
        WHERE type in (N'P', N'PC')

open sprocs
while (1=1)
    fetch next from sprocs into @sprocName
    if @@fetch_status != 0 break;
    select @grantStatement = N'grant execute on '
        + @sprocName + N' to ' + @roleName;
    print N'Granting: ' + @grantStatement;
    exec sp_sqlexec @grantStatement;
close sprocs
deallocate sprocs

Tuesday, December 13, 2005 5:10:03 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [1]  | 
# Sunday, December 11, 2005

Our book is now available.  Go buy it! :)

Professional ADO.NET 2: Programming with SQL Server 2005, Oracle, and MySQL

If you can tell me which chapters I wrote, I'll reimburse you for the cost of the book.  Just email me your guess; you only get one shot!  Only the first right answer wins.

Sunday, December 11, 2005 1:06:48 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, November 28, 2005

Now this is the most useful innovation using .NET technology in the realm of ASP.NET that I've seen in a long time.  Fabrice Marguerie of metaSapiens has released a small framework called PageMethods that provides ASP.NET developers with an easy way to do both retrieval and validation of HTTP parameters as well as retrieval of URLs in a strongly-typed manner. 

I haven't had time myself to really play with it, but looking over the site gives me the impression that it is a well-thought-out architecture and I would think should be something that the ASP.NET team considers adding to the framework in the Orcas timeframe.  It's one of those ubiquitous problems that we've all implemented different solutions for in the past, so it is a perfect candidate for such adoption.

Good job, Fabrice!

Monday, November 28, 2005 1:10:14 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [1]  | 
# Friday, November 18, 2005

I don't think any of us can get away from thinking WWF initially when we hear or read about Windows Workflow Foundation.  The other F's in WinFX (WCF and WPF) both abbreviate and use the natural acronym approach, but obviously, we can't use it for Windows Workflow Foundation.  This point is addressed in Scott Woodgate's blog here, and also in the webcast referenced here.  Scott thinks WF is an acceptable compromise, but I agree with one of the commenters on his blog that for consistency and disambiguation, we should use something with at least three letters.  Another commenter suggests WinWF, which is better but is still inconsistent and almost too long.

I suggest WFF.  The reasons are:
1) It is three letters, starts with W and ends with F, like the other WinFX foundations, so we achieve consistency.
2) It isn't used by anything I know of.
3) WF is actually a common acronym for WorkFlow in our industry.

So it would read Workflow Foundation, with the Windows being implicit, but we still get the consistency, disambiguation, and lack of other cultural references (that WWF has).

What do you think?  If you like it, start using it.  Microsoft has said they're not going to make an official one, so it is up to the populus to determine it, and the way for that to occur is via common usage.

Friday, November 18, 2005 9:45:05 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, November 16, 2005

Yesterday, Mrs. dotNetTemplar wanted to order pizza for lunch.  (I was working from home.)  So I pulled up papajohns.com and put in an order.  About 45 minutes later, the delivery guy arrived, and I met him at the door.  I just happened to be wearing one of the shirts that Microsoft has given me.

"You know, you oughta put that shirt up on eBay," he said.  "You might be able to get two Linux shirts for that one Microsoft shirt."

"Well, ya know, it pays the bills, hehe," I retorted kindly, and he acquiesced on that point, returning to his car.

It wasn't until a minute or two later that the full irony of the exchange hit me.

"You might be able to get two Linux shirts for that one Microsoft shirt," said.. the.. pizza.. delivery guy.. to.. the.. full-time.. professional.. software developer.

Hmm...  maybe he just loves delivering pizza...

Wednesday, November 16, 2005 1:47:10 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [3]  | 
# Tuesday, November 15, 2005

I was thinking today about the proliferation of the "Foundation" terminology in the new Microsoft offerings (e.g., Windows Workflow Foundation, Windows Communication Foundation, and Windows Presentation Foundation).  It occurred to me that the broader foundation for all of this is the .NET Framework and the CLR.  One option that came to mind was Microsoft Intermediate Language Foundation, or MILF.  I can't imagine why they didn't go with that...

Tuesday, November 15, 2005 10:09:15 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [2]  | 
# Thursday, November 10, 2005

Yesterday on the aspnet-architecture list (on AspAdvice.com), we had a little fun going off topic, but rather than continue that discussion there, I thought I just post my thoughts here on something that sprung up (again), namely, the "outsourcing threat." 

Now I'm going to be (potentially) elitist.  Simply put, if you are valuable enough, there is no such thing as an outsourcing threat.  All natural-born Americans have something unique to offer, which is their expertise in American culture and American English.  These are not skills that someone can just pick up at an ESL course or even at a four-year college.  This is something you only get by living here for a long time and, likely, since childhood, and these can be used to your advantage in business.

Granted, I'm not going to say that outsourcing isn't replacing jobs that would otherwise be filled by Americans (that would require living in a fantasy world).  But the jobs that can go off shore are only those that don't require the skills mentioned above.  In the software industry, this is typically going to be low-level support and programming, typically jobs that only require a very basic level of proficiency and little interaction with the business.  I know, for instance, a company that sends off a lot of coding to India, but they still employ a lot of Americans to do the business analyzation and design and even some development. 

The reasoning is obvious--the business is American and Americans like working with Americans because of the aforementioned skills; there is no language or culture barrier to overcome.  Getting software right is hard enough without introducing these barriers, so any company worth its salt will see the value in that and hire Americans wherever interaction with American business is required.

So that's one way in which any American can get the upper hand.  Take advantage of your American-ness.  That's something you can't just ship off shore.  And I can promise you there are tons of businesses, especially smaller businesses, that will never consider off-shoring their work or working with non-American companies.

Another way you can make off-shoring irrelevant to you is simply by becoming good and staying good at what you do.  This requires extra effort, but it will pay off.  It requires passion about what you do.  If you're just in the software industry because you think it is a cakewalk and pays well, you probably won't get very far and off-shoring should be a concern for you.  But if you're passionate about software and translate that into just becoming d**n good at it, you will never lack for employment, whether that's working for a company or as an independent contractor.

Let's quit victimizing ourselves.  American economy is built on the free market, and it has proven time and again that it works.  The latest example of this is the recent oil conundrum caused by the hurricanes.  We had many people predicting ridiculously high prices and suggesting government controls, but by simply going up to where they did, demand was strangled and prices were forced to come down.  You can apply the same to the software industry; it is a matter of supply and demand.  You need to identify where there is a demand and fill it.  There will always be a demand for Americans who understand American culture and business as well as software, and there will always be a demand for good people. 

So rather than complaining about the free market and trying to get the government to control American businesses, which is rarely a good thing, focus on yourself, make yourself an indispensable commodity, and you won't have to worry about the fact that some jobs are being off-shored.

Thursday, November 10, 2005 9:24:05 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [4]  | 
# Friday, November 4, 2005

What the greatest computer ever to be built could not determine (the question for the answer to life, the universe, and everything) is now clear:

What is the revision number of the final release build for the Microsoft .NET Framework Version 2.0?

Friday, November 4, 2005 5:08:51 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, October 4, 2005

Looks like VB is growing up.  It finally has curly braces thanks to LINQ:

Dim People = {New Person {Age := 42, Name := "Erik"}, _
  New Person {Age := 12, Name := "Wouter" }}

It was only a matter of time until they admitted the power of the curly brace.  MUAHAHAHA! :)

To be more VB-like, I suggest:

Dim People = Begin Anonymous Type _
Begin New Type As Person(Age := 42, Name := "Erik") End New Type, _
Begin New Type As Person(Age := 12, Name := "Wouter") End New Type, _
End Anonymous Type As Anonymous Type

Tuesday, October 4, 2005 2:00:56 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [5]  | 
# Monday, October 3, 2005

I guess since Plip already blogged about it, it's public knowledge now.  We've just heard about this revolutionary technology codenamed "Spang."  Of course, now that the word's out, there are parties within Microsoft trying to deny it.  Oh well, it is too cool, almost as cool as LINQ.

[Edited] It now appears there is a web site dedicated to this new technology...

['Nother Update] It seems that some of my colleagues think that a good clean hoax is somehow a serious issue, so our fun has ended.  Everybody just needs to lighten up!

Monday, October 3, 2005 3:46:17 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, September 29, 2005

Since its foundation eight years ago, ASPAlliance has provided articles, reviews, and code snippets targeting ASP and ASP.NET developers. In response to the increasing popularity of .NET and its easing of all kinds of development, ASPAlliance is diversifying to provide content spanning the full range of .NET development, from web to Windows to other devices.

To better signify this change, ASPAlliance is rebranding itself as the Active Software Professional Alliance. We will keep the ASPAlliance moniker, but instead of that indicating a specialty in ASP and ASP.NET topics, it will serve to indicate a more comprehensive resource for software professionals, particularly those interested in Microsoft .NET and related technologies.

So if you've got a hankering to do some technical writing, improve your writing skills through our editorial process, share your knowledge, make a name for yourself, and, to top it all off, make some money, go to our Write for Us page, review our guidelines, and submit an article proposal.  We're looking for articles, book, tool, and component reviews, code snippets, and sample applications that are of interest to .NET developers.  I'd love to see some articles on WCF, WPF, LINQ, or anything you think is really cool and want others to know about. 

Keep in mind that the proposal should be a reflection of your writing skills, so ideally, it will be a thought-provoking summary of what you'd like to write about using your best English.  Take a look at our guidelines to get a better idea of what we're looking for.  I'm looking forward to seeing more great content on ASPAlliance.com, so start thinking and writing.

I'm also always looking for ways in which we can make the reader's experience better.  As noted previously, we have stopped using article paging, we've made many performance enhancements, we've dramatically enhanced and streamlined the editorial process, we've made article submission and compensation better, and now we've broadened our focus to get even more great and interesting content.  But we know we can still improve, so please, email me any suggestions that you have about what you'd like to see from a high-quality .NET developer community site.  Would you like to see forums?  Blogs?  Send me your ideas!

Thursday, September 29, 2005 7:22:55 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, September 26, 2005

There's some good stuff in the latest edition of MSDN Magazine.  I'm talking about the Memory Models article by Vance Morrison and the new Concurrent Affairs column by Jeffrey Richter.  If you don't have a computer science background, or maybe you do and just need a refresher, these articles will help to get you on track when dealing with some aspects of multithreaded programming.  

Mr. Morrison covers some useful low-lock techniques and offers advice of when to use them.  Mr. Richter covers one way to reduce actual locking and increase performance by not dropping to kernel mode using a spin lock, which Mr. Morrison also mentions.  Both of them do so in the context of .NET, including v2, so even if you're a threading expert, you may pick up some tidbits to be aware of when using .NET v2.

I'm also looking forward to reading Stephen Toub's article on High Availability as it appears to be another good one along the lines of writing high-performing and robust code in .NET.  Kudos to the authors and editors on this edition!

Monday, September 26, 2005 12:19:09 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, September 16, 2005

I just finished watching the interview with Anders on Channel 9 about LINQ.  This is one of those things that your grandchildren will ask you about--where were you when you first learned about LINQ? 

Obviously, I'm using hyperbole, but I really do think that this is a huge step in the right direction.  I tried to implement something similar (and I say that loosely) with my DataAspects ORM query syntax.  My problem is that I was limiting myself to C# v1.1, so, for instance, I used an instance of the object to be queried as the source for the criteria of the query when getting a collection. 

For instance:

Order criteria = new Order();
criteria.Customer = myCustomer;
OrderCollection oc = new OrderCollection();
DataAspects.DataProcessor.FillCollection(oc, criteria, "GetOrdersByCustomer");

Suprisingly, this worked for a lot of simple cases, but it broke down for any kind of complex criteria so that you had to resort to ADO.NET and passing a data reader into the object collection builder.  But the key for me--the thing I wanted to achieve was to be able to build my query using all the nice features of VC# like type checking and statement completion.

Well, LINQ does that and a whole lot more.  The thing is that they, thankfully, were not limited by C# 1.1 but were able to invent C# 3.0 and .NET FX 2.0.  So they get to invent new keywords, syntax, etc.  Yeah yeah, I know.. the world's smallest fiddle...  But really, I'm just glad that it's here and that I don't have to worry about solving that problem. :)

One thing, though, is that they are going to go the route of attributes on classes to do the mapping (or so it sounded like), which I like (that's how I was doing DataAspects).  We'll see how that pans out.  Of course, they also will have the nice GUI-generated object layer for your database, which is one step above the typed DataSet.  It still doesn't recommend OOD as a application design philosophy, but at least, via mapping, we'll still be able to take advantage of these features that really are plumbing that we shouldn't have to deal with. 

I know there are different strokes for different folks, and there are plenty (probably most MS developers) of devs who like to start with the database for their application design (ugh!).  My own preference is to start with the problem domain and OOD and then worry about persistence later.  I've got an article submitted to CoDe on this topic, but if they don't want to publish it, I'll probably put it up on ASPAlliance or somewhere else.  In any case, LINQ will make OOP much, much easier and provide even stronger practical arguments for using OOD, and for that, I'm very thankful and eagerly looking forward to digging into it myself.

So if you haven't already, go check it out!

Friday, September 16, 2005 5:47:59 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, September 13, 2005

The Web Platforms and Tools team at Microsoft just went live today with their first public preview of Atlas, which is a server-side API for asynchronous call backs in Javascript to work with ASP.NET 2.0.  Right now, it only works with .NET 2.0 Beta 2, but they intend to follow up soon with a build that works with the PDC bits.

Tuesday, September 13, 2005 11:56:06 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, August 17, 2005

I just heard about the new Nullable type runtime feature being introduced in the August CTP.  That is too cool!  I was initially quite happy about the nullable types provided in 2.0, but after trying to use them, I found them somewhat cumbersome, particularly when dealing with a data reader.  I'm not sure that this change will help that problem much, unfortunately, but it definitely addresses a key pain point for nullable types.  Thanks to MS for listening to the community and making the painful change to make everyone's lives easier! :)

Wednesday, August 17, 2005 9:51:45 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, August 7, 2005
Hi all, in case you haven't heard, the Indigo Roadshow is coming to Tampa this Thursday, August 11th.  They've got the Indigo experts on board, and you get a free book and a chance to win an Xbox.  If you've not heard of Indigo or have been putting off learning about it, this should be a great event to get your feet wet.  And you may want to hurry; space is limited.  Plus, Joe is offering some other stuff for locals turning out.  So come on and check it out.
Sunday, August 7, 2005 5:34:41 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, July 22, 2005

This article has a short clip showing that Microsoft has officially named the OS formerly known as Longhorn to Windows Vista.  The title says something about naming a beta date as well, though I didn't see that in the article.  Of course, I still haven't had any coffee today, so...

Okay, I found it...

Friday, July 22, 2005 9:19:30 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, July 18, 2005

ScaleOut Software has created a really promising ASP.NET state server system.  I haven't had a chance to play with it myself, but it does look good.  Check it out, and check out the review on asp.netPRO.

Updated 7/21 18:14:  I've now had a chance to review some more of the specs and reviews for this product, and the folks at ScaleOut were even kind enough to answer some of my inquiries.  In short, I think this is, from a purely theoretical/design standpoint, the best solution to session management available today.  As a matter of fact, this solution even allows other forms of caching, so not only does it solve distributed session management, it also solves other forms of distributed cache via their API.  Too cool!

If I ever have a need to host a scalable web application again, this product will be at the top of my list to solve those issues.  It will be interesting to see how it fares in the market and what the experiences of those who implement it will be.  I tend to think they'll be great.  I don't get excited about third party tools very often, but I am about this one.  You definitely should look into it.

Monday, July 18, 2005 8:22:12 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, July 17, 2005

Well, Tampa Code Camp went off really well yesterday, and after writing my chapter on caching for ASP.NET 2.0 MVP Hacks tonight, I remembered that I needed to get the code and slides up from my Creating Reusable Application Frameworks session from yesterday since some of you were asking for the code we built in that session.  That download is here

By the way, after I thought about it for a minute, I fixed the little bug that wouldn't get us a good index to add the label at.  Instead of using page, I used ctrl.Parent, which should be (and was) the containing control for the target control.  Once I fixed that, it added the label where we wanted it.  The fix is included in the download.

Also, since it came up a couple times yesterday, the SortableCollectionBase download information is here.

I hope everyone had a great time.  See ya around!

Sunday, July 17, 2005 11:16:29 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [1]  | 
# Friday, July 15, 2005

It just goes to show that we've got a bunch of really great, talented people who are willing to share their time and ideas with others as well as a lot of great folks who want to learn.  Our max of 350 people for the Tampa Code Camp event has been reached, and I'm sure there are those who'd like to come but didn't register in time.

It's going to be a fun and intellectually aggrandizing day tomorrow, and I'm looking forward to seeing a bunch of bright and shiny faces there early on Saturday (that's tomorrow!) morning.  Yes, it is on Saturday, and folks are STILL coming to spend their free time learning.  Wow, what a great lot! 

Hasta mañana!

Friday, July 15, 2005 4:36:22 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, July 13, 2005

As those of you who know me or have read my blog for a while know, I head up editing and development for ASPAlliance.  Since it is a part-time endeavor for all of us, change happens slowly, but over the last year or so since I've been tasked with improving the site, we've dramatically increased our response times, improved our editorial process, (hopefully) improved article quality, and we just recently changed our article submission process and compensation model.  I couldn't have done this alone--by no means--and in fact I have the selfless staff of editors and, naturally, Steve Smith to thank for that. 

Of course, we're not stopping there--we intend to keep trudging forward, doing what we can within our limited time and budget to keep it a top developer community site for ASP.NET developers.  To this end, we need your help!  If you think you have the know-how to write articles for us, we are now providing competitive honoraria for our authors.  So not only do you get the benefit of sharing your ideas with hundreds of thousands of other developers, honing your writing skills, and increasing your marketability, you also get a few coins to boot!  Note that we also pay for reviews of books and components as well as short tutorials (CodeSnips) if you feel more comfortable just showing folks how to do something cool.

So if you're interested in this opportunity, just go to our Write for Us page, review the guidelines, and submit your ideas.  The only way we can keep ASPAlliance interesting is to continue getting new, great content from great minds.  We're looking forward to hearing from you! 


P.S. We're also trying out a no-paging approach to viewing articles--check it out to see what you think.

Wednesday, July 13, 2005 10:03:41 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, July 7, 2005

I know I've already mentioned this, but it's getting close, and we only have limited space available, so I wanted to make sure those of you who read my blog in the Tampa area get a chance.  Joe Healy's been nice enough to put our agenda online, and as you can see, it's pretty impressive for a free event!  One well-known .NET guru, Stan Schultes, is quoted as saying it's as hard to choose between sessions at Tampa code camp as it was at TechEd.  I think you'll agree.

Now I realize this is on a Saturday, which may not be appealing for the nine-to-fivers, but I hope we can all see that going to this can only help your career.  There's something there for everyone from introductory sessions on .NET 2.0 to architectural discussions about objects and SOA.  Heck, there's even a session hosted by local recruiters that will give you the inside scoop on how to get the most out of your skills.  Spend a little of your free time improving your professional knowledge; you can only be better off for having done so.

Thursday, July 7, 2005 7:45:35 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, June 30, 2005

Unless you work on the WSE team, I doubt it, at least not at the time of writing.  I assume this because there is basically only one article on the subject written by Mark Fussell, the Lead PM for WSE, that is an intro to it.  Fine, it is a CTP and only works with a beta of another product (.NET 2), so I can understand that it's not widely adopted.  But I still need answers, as I'm sure others do and will.  So, if you have experience with WSE 3 (and perhaps knowledge of WSE 2 would help), please take a look at these questions:

1) UltimateReceiver.GetClientToken Returns Null

2) Secure Conversation from an ASP.NET Session

If you've got the answers, please either respond on the NG or here. :)

Thursday, June 30, 2005 5:13:40 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [6]  | 
# Tuesday, June 28, 2005

I want to put this out here for anyone else who might run into this problem playing with the Quickstart samples for Microsoft's recently-released WSE 3.0.   To get the WSSecurityUsernamePolicyService sample solution (from the hands-on lab) going, you need to run the CreateSampleVdir.vbs in the solution directory.  Then you'll need to follow the instructions in the "Detailed Instructions," which is linked obscurely towards the end of the certificate setup section.  It links to \Program Files\Microsoft WSE\v3.0\Samples\Sample Test Certificates\readme.htm on my installation. 

When installing the server certificate, be sure to change the drop-down to pick the WSE2QuickStartServer.pfx file; it will let you just install the .cer file (*.cer is the default selection in the certificate importer file type drop down).  Put it in the Local Computer - Personal store.  You will also need to import the WSE2QuickStartServer.cer (that's right, the .cer) file into the Current User 'Other People' store.  To do this, I had to open IE and go to Tools - Internet Options - Content - Certificates - Other People tab because the store wasn't showing up in the MMC add-in.  I later found that it showed up after I added it via IE.

Now, according to the docs, that's all you need to do, but there is one more step that you need to do; otherwise, you will likely get a cryptographic exception saying "bad key," which is so far off the mark as to be funny (if you don't have to waste hours tracking down the real problem).  The problem is that your ASP.NET process identity doesn't have permission to read the server key by default. 

To fix this, you can either go find the file in explorer (on my machine, it is in \Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys) and grant the Users group Read on that directory, which is actually probably the best approach if you're dealing with potentially multiple certificates.  Or you can use the WSE X.509 Certificate Tool, which is part of the WSE SDK to find the cert and then click on the View Private Key File Properties... button to bring up the specific cert's key file perms and grant Users the Read right.  Note this applies on XP and 2000, for 2003, you'll want to grant the IIS_WPG group these perms.

After doing this, I was able to finally run the username with server certificate sample.  It seems almost sad that so much trouble is involved in running a simple sample, but my experience has been that whenever you involve X.509 certificates, the trouble and complications go through the roof.  Microsoft REALLY NEEDS TO WORK ON USABILITY with X.509 certs, especially now that they're becoming the almost de facto approach for securing Web services.  Nearly every time I've dealt with them has been problematic, and one time I actually had to resort to calling PSS, which is unusual for me.  Maybe this is because I'm not an X.509 expert, but then again, most of us aren't...

Updated: If you go through the Hands-on Lab, you'll note they cover these issues above.  This lab would be a good place to start; unfortunately, I didn't start there. :)  But I'd still suggest granting the groups (Users on XP/2000, IIS_WPG on 2003) access to this directory and not the users; this way if you change your service's process identity, you won't have to re-grant permissions for it to see those certs.  And I'd still think that granting these groups read to the directory would be best, so they can see any other such certs you might install.

Tuesday, June 28, 2005 10:49:35 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, June 24, 2005

Developing Compelling User Interfaces with Ease in ASP.NET 2.0
June 30th - 6:30 PM in Tampa - Russ Fustino - Microsoft


Creating Web user interfaces has come a long way since the days of hand-coding HTML and dealing with form postbacks. But even with ASP.NET 1.x you still have to deal with the complexities of maintaining a common look and feel across your site, as well as providing navigation. ASP.NET 2.0 takes Web UIs to a whole new level with a rich set of fresh controls and IDE features. We'll start with a tour of Master Pages and show you not only the benefits at runtime, but during design time as well. We'll show you how easily Themes will let you establish a consistent appearance across your entire site. Finally, you'll discover how managing site maps - including menus, trees and "breadcrumbs" for navigation - is as easy as X-M-L.

By attending this session, you'll learn:

* How to establish a common look and feel for your Web application
* How to manage and customize that look and feel
* How to build dynamic navigation elements for your entire site

This session will illustrate the following:

* Architecture of Master Pages
* Interacting with Master Pages from an ASPX page
* Architecture of Themes
* Working with Themes at design time and programmatically
* Navigation Controls and Site Maps


To Register: http://www.fladotnet.com/reg.aspx?EventID=175

Friday, June 24, 2005 12:23:38 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, June 21, 2005


'Nuff said.

More info at http://www.tampacodecamp.com/.

Rumors are that lunch (pizza and soda) will now be provided by a generous donor...

Tuesday, June 21, 2005 7:33:57 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, June 7, 2005

Microsoft has announced the official launch date for Visual Studio 2005, SQL Server 2005, and BizTalk Server 2006.  November 7th!  Mark it on your calendars; this one has been anticipated for years now (at least by folks like myself).  It's great to finally get definition on it!

In other news, ASPSOFT debuted project Rally, which is the Microsoft .NET-powered battle bot known as The Finalizer.  Too cool!

Tuesday, June 7, 2005 10:16:37 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 

It struck me recently that folks would probably not know until they bought the book that it contains an implementation of a custom ADO.NET 2.0 provider for Active Directory.  It is for one of the chapters that I wrote that demonstrates what you would need to do to implement a custom ADO.NET provider.

I chose Active Directory because I don't like working directly with DirectoryServices.  When I first had the need to interact with Active Directory, I found the API and, indeed, the underlying concepts to be notably foreign.  I think that most devs who are coming from your typical MS background of building applications with relational databases and ADO-like technologies find it somewhat obscure and puzzling to be confronted by the likes of Active Directory and LDAP.

So my goal, apart from demonstrating how to build an ADO.NET provider (which I honestly think most people don't need to know), was to provide something useful that I and others could put to work, making our lives easier.  While the provider itself is not shrink-wrap quality, it does have the basic functionality you'd need to work with user accounts, which I think is the most common scenario for app devs--the greatest benefit of AD for applications is the centralized profile and authentication store it provides.

I would say, and I'm not just saying this because I wrote it, that the book will be worth the price just to get your hands on this provider code, which is available in both VB.NET and C#.  It majorly simplifies dealing with Active Directory by giving you a very familiar API to work with (ADO.NET) and easily enables data binding and updating for common scenarios.  I'd love to see someone take it and build it out into a full-fledged, commercial-quality provider as I think there is definitely a niche for such a product (I'd buy it!).

Of course, I don't want to downplay the value of the rest of the book; it has a ton of other great stuff that will give you all you need to know to become a pro with ADO.NET 2.  So what are you waiting for?  Go get it!

Tuesday, June 7, 2005 10:09:45 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, May 16, 2005

Tampa Code Camp is looking for you.  We are currently accepting sessions on virtually any .NET dev related topic.  If you've got great ideas that you want to share with others, please send us your sessions.  The deadline for new session submissions is mid-June.  So show off your knowledge, help others, and just generally have fun by participating in Tampa Code Camp this July 16th!

More information is available at the Tampa Code Camp site.

Monday, May 16, 2005 6:31:05 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, May 2, 2005
Wally, just told me the cover art and basic description for our book are on Amazon.  Go and pre-order copies for all your friends and family!! :)  Well, at least you can sign up to be notified when it'll be available.  Despite what it says (a bit out of date), the target ship date will be close to RTM of Whidbey (so sometime in the Fall).
Monday, May 2, 2005 7:22:15 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, April 26, 2005
Tuesday, April 26, 2005 10:42:13 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, April 20, 2005

Hey y'all!  Check this out!  The Southern California user groups are putting on a show, a show that sounds terribly like Code Camp.  The catch?  They charge $99. Guess how much we charged for the code camp in Ft. Lauderdale?  $0.  Guess how much we'll be charging for the ones in Tampa, Jacksonville, and Tallahassee?  $0!

Kinda makes you wonder where all that money is going in SoCal...  But more importantly, it should make us thankful that we get it for free!

Just goes to show that Florida ROCKS!! :)


Wednesday, April 20, 2005 12:50:55 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [5]  | 
# Friday, April 15, 2005
For those of you who, like myself, have been dumbfounded by the new editions and licensing models for Visual Studio 2005 and Team Foundation Server, Rob Caron has an unbelievably easy-to-understand explanation on his blog today.  I highly recommend that anyone planning to upgrade or buy VS 2005 and/or team system products read it.
Friday, April 15, 2005 12:29:19 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, April 12, 2005

In case you haven't heard, the ASP.NET Team has done away with the proposed "code beside" model for ASP.NET.  I was recently forced to remember this when porting a Beta 1 demo to Beta 2 (well, more or less Beta 2, anyways).  I'm really glad of the change because it does indeed make moving 1.x to 2.0 much easier; it keeps a familiar programming model, and it addresses some of the annoyances of v1.x.

So I propose that we all forget that the term "code beside" was ever invented.  With the knights of the round table, let us say: "On second thought, let's not go to [CodeBeside].  It is a silly place."

Tuesday, April 12, 2005 3:06:19 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, April 8, 2005

I just ran into a problem that seems like it shouldn't be a problem, though I'm sure there's a perfectly obscure and valid reason it is.  Consider the following:

public class MyBase
{ // ...}

public class MyChild : MyBase
{ // ...}

public class Foo
  public static void Bar()
    MyBase base = GetMyBaseFromSomewhere();
    MyChild child = (MyChild)base;

The last line in Bar throws a System.InvalidCastException: Specified cast is not valid.  Why?  It seems to me that since we're guaranteed that MyChild has everything that MyBase has, it should become the child type lacking values only for the new fields that MyChild has defined.

I'm sure there's some completely reasonable computer sciency reason this doesn't work, such as the data is stored on the heap in a structure defined as MyBase that has no knowledge of MyChild, so it can't possibly know how to become MyChild; all the same, I think it should work.  If there is a way to work around this, I'd appreciate knowing about it.

Looks like this is another place where generics could certainly save the day.  We could specify GetMyBaseFromSomewhere<T>() where T: MyBase, new(), and then we could tell it (in the case above) that we want a MyChild instance.

Unfortunately, this app is in 1.1, so that's not an option.  As I see it, the only alternative here would be for me to define a new method like FillMyBaseFromSomewhere(MyBase base), pass a MyChild instance in, and have it populate the MyBase members on MyChild.  Or (worse), I could define a MergeFromBase method that manually copies the fields from MyBase to MyChild.  Am I missing other alternatives?  Maybe serializing as MyBase and deserializing as MyChild would work?  Anyone?

Friday, April 8, 2005 7:28:01 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [6]  | 
I was just pointed to this diagram of the ASP.NET 2 control lifecycle.  Not only is it immensely useful, it's pretty to boot!  I agree with him--every ASP.NET dev should be familiar with the control lifecycle.  It is of great help when debugging pages and designing advanced features.
Friday, April 8, 2005 1:58:24 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, April 7, 2005

I don't know about the rest of you (probably most of you aren't using custom attributes as much as I), but I find it a kludge to have to override a property definition just to override the attributes on that property.  If you think so, too, please add your voice to this suggestion for the next version of C#:


Thursday, April 7, 2005 9:48:25 AM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, April 6, 2005

It's not official quite yet, but you can go ahead and start learning ASP.NET 2.0 from the experts at the ASP.NET 2.0 Quickstarts site: http://beta.asp.net/QUICKSTART/aspnet/.

I've been told that they may be making tweaks between now and the official Beta 2 release, but don't let that stop you.  There's a lot of good content there!

Wednesday, April 6, 2005 11:44:56 PM (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, March 30, 2005

I just had a strange bug pop up in this framework I've built.  It uses a number of custom attributes.  I have a base attribute and a corresponding collection.  On my collection, there's an Add method that checks to ensure the attribute hasn't already been added before adding, since ArrayList's default implementation is to allow duplicates and nulls.

I declared a type and applied a few of these attributes to different properties on the type, and yet, when I went to add them to my collection, I found that it was only adding the first attribute of a particular attribute type. 

So I looked up the docs on ArrayList.Contains to find out it uses Object.Equals in order to determine if the object is in the list.  So, on a hunch, I looked up System.Attribute, and sure enough, they override Object.Equals.  Here's a link to the help on that.  As you can see, it isn't very helpful.  It doesn't describe how it is changing the semantics of Object.Equals in any way.

So then it was time to pull out my trusty friend Reflector.  Looking at what Attribute.Equals is doing wasn't particularly helpful either because it keeps making external calls, but from what I can gather, it attempts to compare the values of all the fields on the two instances in question.  So you'd think, hey, this is a fair way to determine equality, right?

Wrong.  It doesn't work.  The two attributes I was having problems with had several differing values in their fields, yet this Equals method did not catch that.  Needless to say, this is obviously a bug.  I'd love to hear, in any case, the reasoning why Attribute overrides Equals and, in addition, why the help docs don't explain it one bit.

In the meantime, life goes on, and I had to figure out a separate implementation of Equals that'd work for my needs.  Unfortunately, as far as I can tell, there's no way to call the default Object.Equals method because, as you can see in Reflector, it will simply use objA == objB, which will only redirect you to the most overridden implementation. 

So since I couldn't compare references themselves, which is what I would prefer, I decided to just use two of my properties that were sufficient to meaningfully give the attributes separate identities. 

"Sure," you might say, "you should always do this."  But most of the time I don't see the point; it is often more confusing to do so because, apart from System.String, developers expect reference types to compare equality based on references not values, especially when dealing with custom domain types. 

So I'd say it's generally a bad idea to override Equals unless you really need to because, once you do that, you should also override GetHashCode and, at that point, you may as well just toss the computer out the window and give all your money to charity.  It's just a lot of (usually) unnecessary work that can actually cause confusion and introduce unexpected bugs into your apps.

Anyways, to bring this to a close, if anyone can explain the rationale behind what Attribute is doing, I'd appreciate it.  And if any MS BCL or corlib guys read this, please update the docs on Attribute.Equals to be more meaningful.

Wednesday, March 30, 2005 3:35:39 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, March 29, 2005


To summarize, I'm being told that having the component designer break every time you double-click on a class that inherits from an abstract class is okay.  The absurdity of it is overwhelming.  Just show me the code! :)

Tuesday, March 29, 2005 9:24:51 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, March 17, 2005

In a previous blog, I discussed the difficulties I had in getting activity tracking to work for dasBlog, which ultimately boiled down to the fact that threads in the ThreadPool (which dasBlog uses for logging activity) do not share the impersonated identity of a web application. 

The easy solution, if your hoster will allow it, is to call them up and say, "hey, give ASP.NET's default process identity Modify permissions on the logs directory."  However, if your hosting provider won't do that or if you prefer not to do that yourself, you have another option.

This article, on ASPAlliance.com, describes the steps you can take to get ThreadPool threads to use your impersonated identity.  It describes how to set up application-wide impersonation like your hoster might do it and then shows how to deal with it.  I included a helper class for use with this scenario that can be found as a download on the last page.

If you have any comments or suggestions to make it better, feel free to share!

(Omar has agreed to include this in a future build of dasBlog if I work it into the project for him, so if you'd like this feature let me know.)

Thursday, March 17, 2005 7:11:05 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [2]  | 
# Thursday, March 10, 2005

I was just talking (writing, actually) to some buddies about why we can't have multiple inheritance.  James Avery pointed me to this blog by Wesner Moise, discussing the complications and potential perf hits we could take with MI.  He says that Eiffel's done it using the compiler so that you can have default implementations for interface methods that get emitted where (I presume) you don't implement it yourself.

Truly, I don't care what we call it.  I just would like the convenience of being able to have default implementations of methods that can be shared among multiple types and can be overridden.  If you want to call it default implementations for interface, multiple inheritance, mix-ins, or whatever, I really could care less as long as I don't have to copy and paste the same code over and over (or maintain all those copies) or write calls to helper methods (and write the corresponding helper types and methods).

I also don't particularly care if it is two or three levels of indirection to make the call.  That's really getting a bit overly concerned with performance; developer time, my time, is far more important than a few clicks on the processor, even multiplied a novemdecillion times.  We can upgrade and scale out relatively cheaply, but we only have so much quality developer time.

Thursday, March 10, 2005 3:32:52 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 

Thanks to Server Intellect!  Ever since I put dotNetTemplar.Net up, I've just kind of tolerated that my activity tracking doesn't work.  It was one of those things where you just don't feel like hassling with figuring it out.  dasBlog was sooo easy to set up, I wasn't about to complain or spend much time messing with it, especially since activity tracking is not too terribly important to me--it's just a nice to have.

Fast forward a few months.  I keep getting told by Cindy that she's getting referrals from me, so I finally get fed up and decide to figure it out.  First of all, I upgraded to the latest version of dasBlog, thinking maybe there was a fix in the upgrade.  Not so, but I did get some nice perf enhancements and a CAPTCHA comment spam blocker (and yes, I know these aren't perfect, but they're better than nothing).  And I'm now getting emails for referrals as well.

So my next step, as any good developer will tell you, was Google.  Searching on "tracking not working dasblog" didn't turn up much.  I tried a few variations and found some blogs by folks talking about dasBlog and/or tracking, but nothing along the lines of what I was looking for.

Then I decided to log into the kickin' control panel for my Server Intellect hosting, thinking it might be some setting (probably permissions) that I could change.  Well, I found out I can't do everything in the control panel (i.e., change permissions on directories), but I did find out that the logs directory only had files from 11/21/2004-11/26/2004.  Bringing up those dates in my activity tracker actually showed data (wow!), so I then was almost sure it was a permissions thing. 

Since I can't change/check that myself, I emailed Server Intellect at 6:11am, asking them to check the permissions.  The response, which I received just about an hour later (I guess for once I'm up earlier than someone), was that dasBlog does logging under ThreadPool threads and that my site runs under impersonation.  The configured site impersonated identity has the requisite permissions to write to the logs directory (and the SiteConfig and content--hence most of dasBlog works); however, the ThreadPool doesn't inherit the identity of the impersonated user, so the logging threads couldn't write to the logs directory.  They granted the ThreadPool's identity those perms on the logging directory, and voila, I'm actually seeing activity tracking data again!

Of course, now knowing the problem, a Google search on "ThreadPool thread doesn't inherit the impersonation settings" brings up a blog by Omar Shahine that shows this isn't the first time Server Intellect (formerly EAServe) has run into this problem.  I guess they need to add a "are you running dasBlog" checkbox to their signup form so they know to enable this or perhaps add it to their KB.  I'm not complaining, though--as soon as I reported the problem, it was fixed. 

So thanks again, Server Intellect!  Now maybe I can figure out a way to get the ThreadPool to inherit the identity of the queuing thread without having to know the logon info for that identity...

Thursday, March 10, 2005 7:55:08 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, March 8, 2005
It's official: I'll be presenting Introduction to Object-Relational Mapping in .NET on March 23, 2005 at the Tampa DNUG.  If you're interested, please sign up to come at: http://www.fladotnet.com/reg.aspx?EventID=164.
Tuesday, March 8, 2005 10:01:02 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, March 7, 2005

It's a beautiful problem to have--trying to decide how to organize your code into namespaces (and even classes) meaningfully.  But it can also be paralyzing.  I think I could sit here for hours debating the merits of one way of organization over another until I come up with the perfect approach.  But then, I'd be wasting a lot of time.

So in order to avoid namespace paralysis and not waste time, here is one approach you can use to get past it and move on and yet leave it open to relatively easy change later.  Group related code into one namespace and then use using (Import in VB) statements in the consuming code to use that namespace.  Then if at a later time you find that perfect name for your space, you can change it and only need to update the using/Import statements.  Of course, you run the risk of naming conflicts at that time, but this isn't the best of all possible worlds either.  Deal with it. 

Don't know if anyone else runs into this problem, but I'm in it now and need to move on, so here's my pep talk. Hope it helps some other overly analytical types like myself. :)

Monday, March 7, 2005 2:08:14 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [2]  | 
# Saturday, February 12, 2005

Steve Smith, El “Grande Tiempo” Presidente, did some much needed changes to the ASPAlliance site this week and just deployed them.  These, in conjunction with some database work we did a couple months ago, have really made the site fly.  I want to write an article on the changes I made to the database to help others out when their stuff is performing badly, but no promises!  Suffice it to say (for now) that you should just read up a bit on query tuning and indexing in general as well as lock contention and escalation. :)

Those of you who visited much in the months preceding circa November 2004 will know that it was in much need of help, but I think the site is looking great and functioning really well now.  Check it out and please let me know if you have any problems or suggestions.

Edited: You may need to CTRL-F5 to get the new stuff to display properly in case IE is caching the CSS.

Saturday, February 12, 2005 1:36:14 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, February 7, 2005

Last Friday (February 4th), I gave my notice at GTE Federal Credit Union.  I’ve accepted a position with the angryCoder’s company, ASPSOFT, Inc.  Nothing bad precipitated this event; it is just a matter of timing where I think it just makes sense to move into a more dynamic role, working with folks who are as interested in and as good (or better) at software development and .NET as I am. 

I’ve truly enjoyed my time at the credit union, and I still highly recommend it to folks looking for that kind of position.  I also completely recommend it as a financial institution—I’ve seen how they run the place, and I’ve got almost all of my finances with them now.  If you want a financial institution that is interested in you as an individual and offers great rates on loans and dividends, this is the place to be.

At ASPSOFT, I am looking forward to expanding my skill set further and engaging with diverse clientele while working with some of the best people in the business.  My first assignment, strangely enough, is going to be working with GTE FCU to finish out the main project I was working on.  I’m glad we were able to work this out because it is a win for everyone and will make a very smooth transition.

Going forward, I hope to expand ASPSOFT’s involvement in the Tampa area and beyond.  If you are looking for .NET architecture guidance from industry-recognized and published experts, be it through consulting, outsourcing, or training and mentoring, ASPSOFT can definitely help you out.  Give us a ring and let’s see what we can do!

Monday, February 7, 2005 2:39:55 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [5]  | 
# Tuesday, January 11, 2005
Tuesday, January 11, 2005 4:22:38 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [1]  | 
# Friday, December 10, 2004

I recently found out that CoDe Magazine does not yet have the facility to offer code downloads, so if you've come to my site looking for the downloads, you've come to the right place.

To download the C# (1.1) version:

To download the VB.NET (1.1) version:

To download the C# (2.0 “Whidbey“) version:

Note that I've added a bit of multithreading handling.  I've not tested whether that has been implemented correctly or not, but I can say that it does still work and that I think the lock handling is done correctly.

In any case, I welcome suggestions, questions, comments, etc. to make it better.

Friday, December 10, 2004 4:08:57 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [8]  | 
# Monday, November 29, 2004

FYI: I've got an upcoming presentation on O-R mapping in .NET.  Here're the details:

Time:  Thursday, December 2, 2004 @ 6:00pm
Place: GulfNeTug Dot Net User Group
         Sun Hydraulics
         701 Tallevast Road
         Sarasota, FL

You've probably heard the whispers:  "Psst.  I've heard about this O-R mapping stuff..  seems kinda weird to me; surely it can't work as well as writing my own ADO.NET code..."  The answer is yes; it can and does work as well, and you don't have to bother with code generators or ongoing maintenance of ADO.NET code when you use them.  O/R mappers do ADO.NET for you, allowing you to focus on more important aspects of developing a data-driven application.

J. Ambrose Little will introduce you to the concepts behind object-relational mapping as well as illustrate those concepts by looking at the code underlying an existing O/R mapper called DataAspects.  In addition, all attendees will get a free site license of the soon-to-be-released DataAspects library to use in their own projects.

Recommended Prerequisites:
Familiarity with .NET (particularly ADO.NET) programming.
Familiarity with obejct-oriented design and programming principles.
Familiarity with relational database development, especially SQL Server 2000+.

Monday, November 29, 2004 5:03:16 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [2]  | 
# Thursday, November 18, 2004

Rocky Lhotka provides what I think is a great analysis of the hubbub surrounding service orientation/service-oriented architecture.  It's too bad that so many corporations are swallowing the hype around this and Web services in general and thus giving themselves lots of unnecessary headaches.

Thursday, November 18, 2004 1:33:35 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, November 9, 2004
Version 2.2 of NUnit adds two attributes that, at least, I find very useful--Category and Explicit.
Tuesday, November 9, 2004 8:32:35 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, November 8, 2004
Thoughts about best practices for XML comments.
Monday, November 8, 2004 12:10:10 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [2]  | 

The opinions expressed herein are solely my own personal opinions, founded or unfounded, rational or not, and you can quote me on that.

Thanks to the good folks at dasBlog!

Copyright © 2020 J. Ambrose Little