Some Observations on Marketing, Intellectual Property Protection, and the "Optimal Price Point"

Recently I caved in to incessant badgering and the family went down to Epcot for the day. We live in the Orlando area so it's only about an hour's drive. It turned out to be a fantastic day, although I can tell you that 6 hours of walking in the late May Florida sun will give you two additional presents: 1) A sunburn, and 2) Tired Feet!

While we were there, the kid got his photo taken by a "cast" photographer and his lovely aide at one of the UK country exhibit stores, sponsored by Disney and Kodak. Now this is kinda unique, the photog hands you a color card with a web address and a unique ID on the back of the card. You sign up, log in and - bang! there are your photos. The site is written in ASP.NET, by the way. Now of course, you and I as developers will instantly right-click to attempt to download the little boogers, but they have disabled the context menu with some script. And, they want $12.95 each for a 5X7 print, which I thought was quite excessive, considering the fact that it took the photographer all of 20 seconds to set up and do the 2 shots in a contrived setting.

Not to be daunted, I opened up Tools and looked in the cache, right? Sure enough, no images - but a carefully constructed URL in the form:

Even if you clicked on the URL out of the cache, you would get a page with a stock image that says "Image not available". However, if you massage it a bit and paste it into the address bar of a new browser window:

--Now, there was nothing there that said "if you are successful in defeating our little scheme, you can't have the images", so I am not about to lose any sleep over it. I printed them out on (gasp!) Kodak photo paper for 10 cents, and everybody at home was happy. If the price they wanted was more reasonable, I probably would have succumbed to the "Florida tourist phenomenon" and purchased the print. But. they overpriced the product, IMHO - hence the result.

I guess the folks who wrote the ASP.NET app for them need to go back and revisit their code, eh?

The "bigger picture" lesson here might be, "What's the most effective way to protect intellectual property on the web?". Watermarks on images is one easy way. Previews of a lower than production quality is another. Funky proxy urls to the pictures will work against the average consumer, but as we can see, not for a developer or determined hacker possessing an above-room-temperature IQ. Certainly, license keys and other protection schemes are ineffective at best. But one of the biggest causes of all this activity is overpricing of the product. You see this all the time with developer products. You see a control suite with a price of $499 or even $699. Once the deliverable is complete, you could sell it for $25 and make a profit - the cost of delivery is extremely small. But software outfits don't spend enough time really looking at the marketplace and scientifically looking at the "Optimal price point" - the price at which the most money can be made from your efforts! Usually (not always) -- that optimal price point is a lot lower than the price they are asking for the product.

Abraham Lincoln (attributed) got it: "You can fool some of the people all of the time, and all of the people some of the time, but you can not fool all of the people all of the time."


FeedSearchGator Up and Running!

FeedSearchGator is my newest creation based on the fact that there are now literally dozen of search engines that return results as RSS.

What FeedSearchGator does, very simply, is to take your search query that you put on the QueryString, send it out to currently eleven (11) different engines on a threadpool asynchronously, aggregate the results, remove duplicate links, and return a single RSS feed containing up to several hundreds search results that you can subscribe to in your RSS Feed reader. The engines are: feedster.com, search.news.yahoo.com, beta.search.msn.com/news/, moreover.com, blogdigger.com, waypath.com, blogpulse.com, rocketnews (news), rocketnews (blogs) , newsisfree.com,and daypop.com. I am giving my custom threadpool a 20 second WaitAll timeout since occasionally, one or two of these seach engines take a long time to return results (a very long time, too long to wait for a page).

I'm still refining this, but it is fully operational and I'm open to ideas (including marketing ideas) for the concept. The feed results are cached for 12 hours by query, so if your query is something new it can take up to 20 seconds to get back results. Obviously, if your search term is one that's already been run in the last 12 hours, you'll get your results much faster.

I strip out unneccessary HTML tags to keep the "glop" and the bandwidth down, and results are sorted by most recent pubDate first. I've also put in an REL link to a simple XSL transform in the RSS Document which means you can also view this in your browser too.

Currently the engine is set up to insert up to 3 custom advertisements as actual RSS entries, although this feature is currently turned off.

So for example, if I wanted a custom feed on "XMLHTTP" i would point my RSS Reader to:



Good News for SQLite Afficionados

Robert Simpson, an "early adopter" of the SQLite database and the .NET Framework 2.0 platform, has his first release of ADO.NET Provider 2.0 for SQLite up on SourceForge. Not only did it compile for me with BETA 2 right out of the box, he's really outdone himself.

This thing supports user-defined functions, and the ProviderFactory model as well: To Quote:


  • DbProviderFactory support, just add the XML below at the machine.config and/or app.config level.

  • Full support for ATTACH'ed databases.  Exposed as Catalogs in the
    schema.  When cloning a connection, all attached databases are automatically
    re-attached to the new connection.

  • DbConnection.GetSchema(...) support includes the MetaDataCollections,
    , Columns, Tables, Views, Catalogs
    and Indexes keywords.

  • Enhanced DbDataReader.GetSchemaTable() functionality returns catalog, namespace
    and detailed schema information even for complex queries.

  • Named and unnamed parameters.

  • Full UTF-8 and UTF-16 support.

  • Multiple simultaneous DataReaders (one DataReader per Command however).

  • Full support for user-defined scalar and aggregate functions, encapsulated into
    easy-to-use base class in which only a couple of overrides are necessary to implement
    new SQL functions.

  • Full support for user-defined collating sequences, every bit as simple to implement
    as user-defined functions and uses the same base class.

In order to use the SQLiteFactory and have the SQLite data provider enumerated in
the DbProviderFactories methods, you must add the following segment into either
your application's app.config or the system's machine.config located in the %SystemRoot%\Microsoft.Net\Framework\v2.xxxx\Config

<add name="SQLite Data Provider" invariant="System.Data.SQLite"
support="3F" description=".Net Framework Data Provider for SQLite"
type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />

You can get your hands on these goodies here,
including the 3.21 version of the SQLite C++ sources as of today, May 25.

Thank YOO, Robert! One Swell Dewd!

Quotations Page and RSS Feed Up!

Over the last few years, I"ve built up a database of quotations from famous and some not so famous entities, built from a variety of sources (yup - even Dexter Dotnetsky is in there!). My database now has over 43,000 quotations from nearly 8,000 authors organized by over 1,300 subjects. Up until now, I really haven't done anything with it but now that ASP.NET 2.0 is coming and I have my ASP.NET 2.0 "playground" site , myidentityplus.com, I've got a neat place to put my experiments.

I have a random "Quote of the Day", which is available as an RSS Feed as well, and you can search the database by Author, Subject, or even by a word or phrase to be found within the quotation body. This page is written in ASP.NET 2.0. There is also a link to submit a quote for consideration in the database.

You can Check out the quotations page here:

It doesn't have a MasterPage yet but everything seems to be working correctly, so try it out. The Daily Quotation feed item changes every 24 hours.

My next offering will be my FeedSearchGator or GatorSearchFeed? or maybe SearchFeedGator (Well, maybe something else!) - an engine that takes your search query and aggregates it over 8 to 10 RSS search engines, returning you a single feed with no duplicate links! Look for that one soon. Probably gonna have to put some ads in that one cause I know it will suck bandwidth big time!


When this came out, I was . . .

Tonite we watched Divorce, Italian Style, Pietro Germi's hilarious 1961 satire of Italian marital conventions that recently was issued on DVD. Ferdinando Cefalu, a handsome Sicilian nobleman (Marcello Mastroianni), longs to marry his beautiful young cousin Angela. There's only one problem: he's already married, and at that time you could not get a divorce in Italy. Living in a society that forgives crimes of passion, Ferdinando devises a plan. He plots to prove his wife an adulteress, after which he can kill her and marry his cousin with impunity. As one would expect, there are twists and turns, and a surprise ending.

I swear, even though you are reading the English subtitles and listening to the Italian- only audio, you do not even notice that this movie is (gasp!) in black and white!

Hollywood, what happened? You used to be able to put out movies of this quality. Too bad.


Intellisense on Steroids in ASP.NET 2.0

Whoa! I'm working on some neat ScriptCallback stuff with a database of quotations I've been working with in Visual Studio.NET 2005, and I just noticed this. When you have client script in ASP.NET 2.0,
and you need to debug it (even if it's dynamically generated script from the Page.ClientScript object), you get some really cool new Intellisense on it. This picture is debugging Client - side javascript, folks:

-- by the way, if you are wondering why any of the script callback demos you've seen for ASP.NET 2.0 don't work, its because the GetCallbackEventReference method got moved into the Page.ClientScript class. So,

Page.GetCallbackEventReference(this,"arg", "ReceiveServerData", "context");

now needs to be:
Page.ClientScript.GetCallbackEventReference(this,"arg", "ReceiveServerData", "context");

If you are interested in working with script callbacks for ASP.NET 2.0 in a strongly-typed fashion, and would like to see an example of it done "the right way" instead of the "BS AJAX clone" way, I recommend that you visit Bertrand Leroy's blog and see the gotdotonet workspace for his RefreshPanel infrastructure.


VB.NET vs C# Debacle Rages On

There are a few "givens" that one must consider and accept when dealing with this obviously sensitive issue.

First is that you aren't going to make case-sensitivity go away. It's built into too many languages, operating systems and standards. XML, UNIX, C++, and of course C# just to name a few. If you write VB.NET code you may wish to consider that fact, especially if you anticipate that programmers using other languages are going to be using the classes you write. Personally, I find case sensitivity to be a good thing. It forces me to think a bit more and serves as an additional check on writing quality CLS-Compliant code. Think of it as the "literary approach": If you are the kind of individual who -- through either laziness or lack of education -- can't spell, use proper English grammar, capitalize words correctly, and you do things in your language such as use the word "loose" when you really mean "lose", then probably VB.NET would be a better fit for you. And, don't use Javascript. It's case - sensitive too. Point is, you can rail against case-sensitivity until your face turns blue; it's just not going away; yet this seems to be one of the major gripes of "VB.Netters" about not wanting to learn / use C#.

Second is that VB.Netters, as a Gestalt, have a large contingent of proponents who defend VB.NET not with logic, but with a religious fervor that occasionally borders on insanity, taking any jab at VB.NET by anybody at all as some kind of personal attack. That's obvious if we simply read all the blogs about Richard Grimes' parting piece in DDJ. Even Carl Franklin, whom I'd otherwise consider to be a pretty classy guy, seems to have jumped into the sewer on this one.

There are many programmers who write terrific code with VB.NET. Unfortunately, there are far more who do not, and according to Nigel Shaw, who has a recent "culture" piece at CodeProject. one of the primary contributing factors is the fact that the language was created out of a culture that permits low-quality, error-prone code to get compiled.

My personal view about this is mainly born out of the culture aspect. I believe that I understand the history and culture that were responsible for the so-called "VB" mentality, because I was a part of it for a number of years. I didn't get as much exposure to the so-called "C# culture" until after I had made the conscious decision to switch to C# as my primary programming language when the .NET Framework came out. This decision was not made easily; I had become very "comfortable" with Classic VB and VBScript. Inertia (resistance to change) is a very objective thing - we all feel it.

However my decision was made based on what I considered at the time to be overwhelming facts, figures and arithmetic in favor of taking the much "harder road", if you will. It was not until I worked for a company that enforced what I now consider to be a particularly mindless "VB.NET Only" development strategy that the full effect of what can go wrong with VB.Net came to the fore. Needless to say, I no longer work there, although I am still exposed to some of the absolutely crappy code that VB.NET programmers have left for me to work with at my current place of employment. Suffice to say, our developer group all feel a sigh of relief now that we have almost totally converted all this VB.NET code that we inherited to C#.

And the final "given" is that neither C# nor VB.NET is going away anytime soon. So, we all might as well get comfortable with each other and learn to try and play from the same score. For VB.NET programmers, this really means understanding that the language you are using has built-in crutches that were primarily put there to hopefully ease your transition from classic Visual Basic and which have very little to do with the .NET Framework proper. The Framework and the CLR already has everything it needs and if VB.NET did not exist, nothing in it would change. Please understand that. For C# programmers (and VB.NET programmers too), especially those that did not come from C++ , JAVA or other more object-oriented programming environments, it means being willing to throw away the spaghetti-code techniques you may be used to, and learning to deal with true objects using encapsulation, polymorphism, interfaces, virtual and abstract classes, and much more.

Another important thing to consider: You can apply the CLSCompliant attribute on an assembly (or a program element) and have the compiler check if your code is CLS (Common Language System) compliant. This means it works properly when consumed by other .NET languages. For example, you can place the following attribute on your .NET AssemblyInfo.cs files:

[assembly: CLSCompliant(true)]

Some of the things the compiler checks:

Class and member names cannot differ only by case. For example, you can't have one property named Counter and another named counter. This is important for cross-language compatibility since VB .NET isn't case sensitive.

Overloaded class methods cannot differ only by out or ref parameter designations.

Publicly exposed members cannot start with an underscore ( _ ).

Operators can't be overloaded

Unsigned types can't be part of the public interface of a class

Unfortunately, although you can apply the CLSCompliant attribute in VB .NET, the VB .NET compiler doesn't check for CLS compliance. "Ah," you say. "Now I understand why ONLY C# was submitted to and accepted for language certification by ECMA." One point I should make here, based on some recent comments, is the fact that you can create CLS- Compliant classes with VB.NET. And you should consider doing so. As I mentioned above, everything you need is already in the BCL and you do not need to use the namespaces with "VisualBasic" in their names. VB.NET is not a "bad" language; it just allows you to get away with perpetuating bad programming habits. That's the culture part.

For VB.NET programmers, If you turn on Option Strict and Option Explicit, and avoid using the crutch class methods like CType instead of DirectCast, and use the Framework Convert class instead of "CInt", you are well on your way to writing CLS - compliant code. And for Heavens sake, learn to use the Exception class and its derivatives -- and learn it well. Oh, you won't like it, because all this puts the VB.NET compiler pretty much on the same level as writing in C#. You'll be forced to really think. You will often hear that both VB.Net and C# generate the same MSIL code. THEY DO NOT. However, if you follow the above suggestions, it will at least be similar in its performance characteristics. You can write code in VB.Net that does not depend on namespaces with "VisualBasic" in their name. Try it -- you'll be surprised at the new power the .NET Framework offers to you. You still won't be able to use pointers and other unsafe code constructs, but that's not the main issue.

And -- if you take my advice and still want to be a VB.NET programmer, you'll become a better one. Who knows -- you may very well decide to abnegate your relationship with that beloved VB as I did, and decide you'll actually be better off with C# after all.

The debate really begins to take a back seat when you begin writing managed code with C++ -- which has become a good portion of what I am doing now. Managed C++ and the ability to generate mixed mode assemblies -- is absolutely awesome!

As a final note, I didn't initially take up C# because I had a pressing need for pointer arithmetic or operator overloading, although I occasionally need them now. I do know why, once I learned C#, that I stopped writing VB.Net. I just happen to prefer C#’s syntax: less redundancy, fewer unnecessary keywords and language constructs. I don’t want to have to write "Dim foo As Bar" when I can simply write "Bar foo".

VB.Net doesn't look the way it does because some language designer thought carefully about
what would make a good syntax for a language, but because it was advantageous for Microsoft to be able to persuade VB6 programmers that VB.Net was just the latest upgrade to their favorite language in order to get them to adopt .NET.

I wish VB.Net would go away because there isn’t any real, compelling technical reason for it to exist. It exists mainly because Microsoft needed to persuade the VB6 developer community to move away from a language it was going to abandon, and it has inherited many of the crutches and ugliness of VB6 without maintaining any real continuity with that language. C# is not perfect either, but at least it’s not a half-assed attempt to fulfill an essentially deceitful marketing campaign.


Dr. Dotnetsky must have gone to the movies too...

I just got an email from Dexter Dotnetsky again. He says he's getting ready to do another rant on eggheadcafe.com (heh - that is, if we let him post it). He sent the photo below:


fil i bus ter != debate;

The use of obstructionist tactics, especially prolonged speechmaking, for the purpose of delaying legislative action.
An instance of the use of this delaying tactic.
An adventurer who engages in a private military action in a foreign country.

--Term used to designate obstructionist tactics in legislative assemblies (who knows-- maybe even in .NET assemblies). It has particular reference to the U.S. Senate, where the tradition of unlimited debate is very strong.

What's particularly interesting is the origin of the word:

In the 17th cent. the term was applied to buccaneers who plundered the Spanish colonies in the New World. In the 19th cent. the word was used more in reference to adventurers who organized and led, under private initiative, armed expeditions into countries with which the country from which they set out was at peace. Complications between the governments involved were likely to result. There was a series of filibustering expeditions from the United States against Cuba, Mexico, and Central and South American countries in the 19th cent., some of them led by citizens of the United States.

Does this all sound familiar in a modern setting?

Draw your own conclusions, but remember-- it's your and my taxes that pay for this imbecility. You can run the government, have a debate, and vote on it. Fil-i-bus-ter != debate. Leave the Stone Age for Barney Rubble.


Xenophobic email attacks use mutiple NonDelivery messages as vehicle for D.O.S.

[Subtitle: "Invasion of the Zombie PC's"]

Nearly a year ago , Joe Wein correctly predicted that if this security hole was not corrected, it would lead to huge abuse. And, wasn't he ever right!

What is happening is this: Sober.G / Sober.H requests copies of its mails to be sent to 40 additional made-up addresses at a time and since most of these are invalid, whoever has his email address abused by Sober may end up with bounces (Non-Delivery Notifications, NDN). The email servers are mindlessly "doing their job" - and actually creating this flood of multiple DOS (Denial of Service) attacks.

I quote Mr. Wein:

"A combination of generating multiple bounces for a large number of invalid carbon copy addresses and attaching the complete original mail is dangerous. Unless such issues are addressed soon and on virtually all vulnerable mail servers, sooner or later someone will abuse this well-documented gaping security hole."

This is an excellent example of how to make the enemy unwittingly turn its weapons against itself.

Read more here, including a downloadable whitepaper on the subject.

One of the ways you can help protect your address from being harvested is to encode all "Mailto:" links on your site's web pages. A full-featured easy email-encoder that will generate
the script to do this can be found here. It's far from 100% protection, but at least it's a start. If your email address appears in plain text on a web page, you can pretty much BET that it's getting harvested by these bastards.

Read it and weep, folks.


Team Development - a dying art? Not at Microsoft...

I don't know about you, but being a developer who has made a whole bunch of money by focusing on Microsoft development platform / technology, I have more than a casual interest in what is going on at Microsoft.

I have a number of friends and acquaintances who work there, but I am not the kind of person who likes to bother people or ask prying questions.

However, I've noticed a major sea-change at MS in the last couple of years, and I suspect that Ballmer is primarily responsible for it. This is the focus on "Customer -centric" -- and more specifically, "Developer-centric" information. I feel much more comfortable working with internal MS people; I've had intros through my MVP lead, Rafael Munoz, to some higher-ups that have been exceptionally forthcoming with information and help when I needed it, and I've tried not to abuse the privilege.

The MS blogging phenomenon has contributed to this "binding" with the developer community. The Product Feedback Center site is another example of this paradigm shift. There are other examples.

Recently I read a post on Jay Bazuzi's MS blog about their ZBB (zero bug bounce) effort, which I recently alluded to from Scott Guthrie's blog focus - this is a revealing look at a concept which really underscores how teams can work toward a goal.

Their team goals are clearly focused, measurable, and sensible. There is real leadership. They have a timeline, they have clearly demarcated priorities, and most importantly - it's obvious that they work together and help each other. A lot can be learned by carefully reading the new quality of outbound information sharing coming out of Microsoft.

Michael Jordan got it in just nine words:

"Talent wins games, but teamwork and intelligence wins championships."

Generic T-SQL Stored Proc to generate RSS from any Table

This uses my UDF , "fnRFC822Date" from a previous post.

You simply supply a tablename, the names of the columns for the various RSS items
and channel items, a URL prefix for the link,
and the maximum number of items, and you get back well-formed (I hope) RSS!

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[usp_GenerateRSS1]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[usp_GenerateRSS1]


CREATE PROC dbo.usp_GenerateRSS1
@RSSTableName varchar(50),
@ChannelTitle varchar(250),
@ChannelLink varchar(250),
@ChannelDescription varchar(500),
@ItemTitleColumnName varchar(50),
@ItemLinkColumnName varchar(50),
@ItemDescriptionColumnName varchar(50),
@ItemPubDateColumnName varchar(50),
@LinkUrlPrefix varchar(200),
@maxItems int


Declare @strSQL nvarchar(500)
set @strSQL ='select top ' +cast(@maxItems as varchar(3)) +' IDENTITY(int,1,1) AS ID , ['+
@ItemTitleColumnName +'] AS [TITLE], '+@ItemLinkColumnName +' AS LINK, ['+@ItemDescriptionColumnName +'] As [DESCRIPTION],'+
'dbo.fnRFC822Date(' +@ItemPubDateColumnName +') AS pubDate into TEMPRSS '+
' from ' + @RSSTableName + ' order by ' + @ItemPubDateColumnName + ' desc'
EXEC sp_ExecuteSql @strSQL
declare @results1 varchar(8000)
set @results1='<?xml version="1.0" ?><rss version="2.0"><channel><title>'
set @results1=@results1 +@ChannelTitle +'</title><link>'
set @results1=@results1+@ChannelLink +'</link><pubDate>'
set @results1=@results1 + dbo.fnRFC822Date(getUtcdate()) +'</pubDate><description>'
set @results1=@results1 +@Channeldescription +'</description><language>en-us</language>'
declare @max int
Select @max = max(ID)from TEMPRSS
declare @ctr int
set @ctr=1
declare @tit varchar(250)
declare @lnk varchar(250)
declare @desc varchar(8000)
declare @pubDt varchar(70)
WHILE (@ctr<=@max)
select @tit =[title] ,
@lnk=@LinkUrlPrefix +CAST(LINK AS VARCHAR(200)),
@desc=cast([description] as varchar(8000)),
@pubDt = pubDate
where ID=@ctr
set @results1 =@results1 +'<item><title>'+@tit +'</title><link>' +@lnk
set @ctr=@ctr+1
Set @results1=@results1+'</channel></rss>'

select @results1



DECLARE @RSSTableName varchar(50)
DECLARE @ChannelTitle varchar(250)
DECLARE @ChannelLink varchar(250)
DECLARE @ChannelDescription varchar(500)
DECLARE @ItemTitleColumnName varchar(50)
DECLARE @ItemLinkColumnName varchar(50)
DECLARE @ItemDescriptionColumnName varchar(50)
DECLARE @ItemPubDateColumnName varchar(50)
DECLARE @LinkUrlPrefix varchar(200)
DECLARE @maxItems int

Set @RSSTableName = 'RSS'
Set @ChannelTitle='this channel'
Set @ChannelLink = 'http://www.booboo.com'
SEt @ChannelDescription = 'the best channel ever'
SET @ItemTItleColumnName = 'Title'
Set @ItemLinkColumnName = 'Link'
Set @itemDescriptionColumnName ='description'
Set @itempubDateColumnName ='pubDate'
Set @linkUrlPrefix = 'http://www.booboo.com?'
Set @MaxItems =20
-- Set parameter values
EXEC @RC = [TEST].[dbo].[usp_GenerateRSS] @RSSTableName, @ChannelTitle, @ChannelLink,
@ChannelDescription, @ItemTitleColumnName, @ItemLinkColumnName, @ItemDescriptionColumnName,
@ItemPubDateColumnName, @LinkUrlPrefix, @maxItems

[Note to self:] Ahh, this still needs a little work, but I'm leaving it up in the meantime to see if anybody has feedback or ideas.


Rich Turner of Microsoft blogs about his diatribe over the SOA acronymn "invented", hyped and promoted by the likes of Gartner and other groups over the last couple of years. ("AJAX" is the latest such gaffe, simply a marketer- packaged new "name" for something people have already been doing quite well for a long time, thank you).

Specifically, I agree with Rich's posture "We do strongly subscribe to the notions of SO as abstract guidance and goals for building distributed systems. ...... but we don't have a SOA because we don't believe such a thing exists, and if it is, its too poorly defined for us to adopt."

RIch continues to explain that SO(A) is only part of the story and talks only about part of building a solution: how to construct a system from loosely coupled, cooperative services, but makes no mention of how to visualize data, how to integrate devices, how to analyze and mine information, and so on.

A real architecture (that's the supposed "A" in SOA) takes a lot more than some ideas, a bunch of marketing hype from self-appointed gurus, and the latest nom du jour, no matter how important or sexy it may sound to the uninitiated. Really, I always thought SOA stood for something else anyway...

You know, as you mature, you don't get "B'd by the B" as much as when you were younger. Some things are timeless, like Miles' trumpet solo on Freddie The Freeloader, with 'Trane picking up right after. SOA? Heh! Don't waste my time.

And I seem to remember, Rich, that you were also working on a whitepaper that compared .NET vs. COM Interop MSMQ performances. I'm still looking....


Transact-SQL RFC822 Date / Time Function for Stored proc RSS Generation

Have you ever wanted to generate RSS from a Stored procedure? It's easy, until you get to the RFC822 date requirement!

Believe it or not, I could not find this anywhere-- I actually had to cobble it together from pieces myself. Enjoy:

5/17/05 NOTE: oj commented with a much better, shorter version which I've used to replace my original and is posted below:

IF OBJECT_ID('[dbo].[fnRFC822Date]', 'FN') IS NOT NULL DROP FUNCTION [dbo].[fnRFC822Date]
CREATE FUNCTION [dbo].[fnRFC822Date]
@Date datetime
RETURNS nvarchar(70)
RETURN(LEFT(DATENAME(dw, @Date),3) + ', ' + STUFF(CONVERT(nvarchar,@Date,113),21,4,' GMT'))

-- example:
--print dbo.fnRFC822Date(getdate())


Thu, 12 May 2005 21:29:29 GMT


"Mr. ASP.NET" Cranking hard on June 3 zero bug bounce for ASP.NET 2.0


I especially like the part about:
"One of the big changes we are making for RTM is to further enhance the migration wizard in Visual Studio 2005 to help handle a number of the common cases that weve seen when upgrading applications with Beta2. In particular, we are spending time making sure that all of the model changes we made (item #1 above) are automated so that existing customer apps should for the most part just work without manual changes required. A few of the cases of model change behavior that weve seen that have required manual developer changes in Beta2 but should now be automatic for RTM when first opening the project and running the migration wizard ..."


About the "Study Path" for new technologies

This is nothing earthshaking; its something I feel strongly about, however. This relates to your personal philosophy about how you handle new technologies as they move through the BETA and into the release phase. Specifically, I am talking about Visual Studio.Net 2005, Sql Server 2005, and .NET Framework 2.0. Your views may differ.

Generally speaking, when you get to the point of a BETA 2 or later with some sort of "Go Live" permission license, it's time to crack the books and get serious. RTM is not far away, the Assembly version numbers will not change, and most of the changes (obsolete / new or deprecated) have already been "baked".

What remains is tuning, fixing little things that are still not working 100%, and codebase optimizations that don't really affect method signatures, namespace or class names, and the like.

What I guess I'm trying to say is that its OK to start developing production software with VS.NET 2005 Beta 2. 95% of the software you write from this point on will work great under RTM. I know people that actually started developing production sites and software with VS.NET 2005 a year ago.

There are two kinds of development environments in the world - the ones that say "No, we won't install any beta software or platforms, and we don't want our people working with it", and the ones that say "This is exciting and has a lot of new features, let's set aside some time to work with this is a measured way so that we can be ahead of the curve, be in a position to exploit new technological advances, and also to look at what we are currently doing with a clearer view toward how it will fit or need to be changed for the newer platform."

If you are in camp number 1, I don't want to work for you, because you are "behinder than you think", and you will likely ALWAYS be that way. You can come up with all the rationalizations you want, but you aren't going to impress me. I just want to "Be there" and you are gonna hold me back. We simply don't FIT.

There is a lot of studying that needs to be done with .NET 2.0 and its associated tools. My philosophy is to try and understand as much of it as I can in advance, before I even think i will need it. The reasoning behind this is really quite logical. If I don't study generics and iterators now, how will I ever know what they can do for me later on? In other words, if I don't understand or know about a particular technology or feature, how likely is it that I'll have a broad enough architectural view of business problems to even know that I should consider using it in a solution?

An example of what I am talking about is Community Server - Rob Howard and his group were, in varying degrees, involved in the development of ASP.NET 2.0 and you can see the influence in the current version of their forum / blog software for 1.1. They have stuff in there for personalization and providers and so-on that they knew would be in ASP.NET 2.0, maybe under a slightly different name, and they didn't have it yet in Framework 1.1, so they rolled their own for version 1.1 and it made the software better. And, when they go to convert it and upgrade it for 2.0, their job will be that much easier.

Made my point. Crack those books, dewds and dewdettes.


Remember the old .NET Framework ASP.NET "Class Browser"?

Well, here's my take on an ASP.NET 2.0 version

That's my new ASP.NET 2.0 "playground" courtesy of the nice folks at CrystalTech.com.

Just a start, there will be a lot more soon! Enjoy.

[NOTE TO SELF:] The Classbrowser is missing from the ASP.NET 2.0 Quickstarts. However, you can download the Samples from MS Downloads, and
that one actually does have it. So, I'll update my little experiment to the actual, real one.

Debugging a .Net Framework Windows Service and ASP.NET 2.0 version switcher

I don't usually "parrot" other people's contributions, but in this case the solution is so elegant and simple, I'll make an exception.

Lee Humphries has a short article on codeproject.com here about this.

Essentially it boils down to telling your service to kick off and run in Debug mode - just not "as a service":

// The main entry point for the process
static void Main()
#if (!DEBUG)
System.ServiceProcess.ServiceBase[] ServicesToRun;
ServicesToRun = new System.ServiceProcess.ServiceBase[] { new Service1() };
// debug code: allows the process to run as a non-service
// will kick off the service start point, but never kill it
// shut down the debugger to exit
Service1 service = new Service1();

Man, it doesn't get any simpler than that! Nice work, Lee!

On an unrelated note, Denis Bauer's ASP.NET version switcher works great with ASP.NET 2.0. This is essentially a GUI wrapper over ASPNET_REGIIS.EXE and will make your life much easier. Shows a tree of all your IIS virtual directories including the version highlighted by color in the tree, and allows you to change the version of ASP.NET runtime that the app will run under. Especially useful for Windows Server 2003 x64 edition where I still haven't figured out how to get the ASP.NET tab to show up in IIS as a snapin. Get yours here.

The only thing you need to do now, Denis (if you are listening) is add the option to add the -wow64 switch at the very end, for users running 64-bit Windows.


ASP.NET 2.0 QuickStart: That's what it is!

We get lots of posts on eggheadcafe.com from newbies asking how to perform very basic ASP.NET tasks. Almost without exception, when asked if they have looked at the "QuickStart" the answer is more or less, "what's that?".
ASP.NET 2.0 also has a Quickstart. If you didn't install it, look here:

C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\QuickStart

If the folder and its files / subfolders are there (you installed the SDK), just fire up IIS, create a new "Virtual Directory", and point it to the above path. Name it "quickstart"

Set the ASP.NET Tab on IIS to use the 2.XXXX Framework, and request "Http://localhost/quickstart", and you will be on your way.

By the way, the "sourceview" element in the web.config is mistakenly left to the settings of the last Microsoft developer responsible for it before the build (most likely NOT where yours will be), so change it to :

<add key="root" value="C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\QuickStart" />

Hey folks, there's a lot of new stuff to learn about in ASP.NET 2.0. I'm a senior - level dude, and I'm taking the time to go through this carefully, because it's very well put together. So, take a weekend, and do your homework like me! You will thank me later.

Not to sound like a broken record, but--

No pain, no gain. RTFM. When all else fails, don't forget to press "F1".