Thursday, November 08, 2007

So here’s the height of shady customer service this week … I canceled my Urge (now Rhapsody by Real) account this morning. First problem is that you cannot cancel online, you have to call into their customer service number to cancel. I guess they haven't heard of this Web 2.0 thing, but then if I didn't have the opportunity to talk to someone, they couldn't try to their confusing tactics outlined below.

After the typical customer service dance of trying to keep me as a customer, the CSR tells me that he has sent me an e-mail confirming that my service is paid through 11/29 and should I want to continue the service, I need to do nothing. If I want to cancel the service, I just need to reply to the e-mail.

Huh? I was calling him to cancel the account. Cancel. He just spent 3 minutes asking me why I want to cancel. Confirming that I want to cancel. I was pretty clear. I want to C-A-N-C-E-L my account.

And instead I get this shifty e-mail with the following verbatim text (emphasis mine):

As Per our conversation, please consider this e-mail as confirmation that your Rhapsody membership is paid up through 11/29/07 . If you would like to continue your membership at that time, no further action is required. However, if you should decide that you would like to cancel at that time, you may do so by contacting Customer Service prior to that date or simply by responding to this e-mail with your request.

Of course, now I need to follow up with yet another phone call to ensure that they received my reply and are canceling my account, effective immediately. Not the way to build trust, Real, and I will definitely not be back after that stunt.

Thursday, November 08, 2007 5:27:26 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, August 15, 2007

One area in which iTunes is sorely lacking is the ability to automatically recognize changes to the physical song files within the library and update itself accordingly. Windows Media Player (and most other media players on the face of the planet) do this naturally. A new file arrives somewhere under C:\Users\Kevin\Music and WMP automatically updates the library to reflect the addition. Likewise when deleting files. 

I recently equipped all members of Casa dé Hambone with iPods of some fashion. The kids each received an iPod Shuffle. Mrs. Hambone received an iPod Nano. And I traded in a non-working 40GB iPod for an iPod Nano as well.

My challenge was to automate the process of importing songs into a secondary iTunes library. I wanted to rip CDs from the comfort of my desk and have the songs automatically appear within iTunes on my wife's computer. Furthermore, I wanted to rip the CDs to WMA using Windows Media Player and have iTunes convert them to AAC on the import.

Oddly enough, Apple provides an entire COM-based iTunes SDK that enables you to extensively automate iTunes, including the conversion process. I must say that I'm really impressed that Apple has gone to this extent, especially on a Windows system.

For my purposes, the iTunesAppClass.ConvertFiles2 method seemed like just the method to use. As you can drag and drop an entire list of WMAs into iTunes, and iTunes will gracefully begin a batch conversion process, it only made sense that this method was exactly the thing for which I was looking. The only "problem" was the ConvertFiles2 method signature:

iTunesConvertOperationStatus ConvertFiles2(ref object filePaths)

Huh? It would make sense that ConvertFiles2 would take an array of strings, but a ref object? Attempting to pass an array of strings to ConvertFiles2 - as if I by sheer willpower I expected this to work - results in a "cannot convert from string[] to ref object" error at compile time:

string[] files = new string[] { ... };
iTunes.ConvertFiles2(files);

And trying to cast an array of strings to a ref object on method call results in "A ref or out argument must be an assignable variable" at compile time:

string[] files = new string[] { ... };
iTunes.ConvertFiles2(ref ((object) files));

Not a good sign.

So what to do? Well, it turns out that with casting prior to the method call, we can coerce an array of strings into an object and then pass a reference to that object:

string[] files = new string[] { ... };
object filesAsObject = (object)files;
iTunes.ConvertFiles2(ref filesAsObject);

In this instance, I believe I'm fortunate that ConvertFiles2 does not actually modify its incoming list of files. Instead, we see a less-than-stellar method signature resulting from COM interop and there's not much we can do about it, but it does work.

The result is a Windows application which sits politely in the Taskbar Notification Area waiting for new WMA files to arrive and then, en masse, hands them over to iTunes for conversion to AAC. I can now rip kid-friendly music from my comfy chair to a shared drive on the casadehambone.com network and have it magically appear within iTunes on my wife's computer where it is then synchronized down to the kids iPods.

Near nirvana.

I'll gladly post the application and its source code as soon as I can come up with a name for this handy little application. All of the usual suspects (iTunesCommander, iTunesImporter, iTunesAgent) seem to already exist. Any ideas?

Technorati Tags: , , , ,
Wednesday, August 15, 2007 12:11:51 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [1]  | 
 Thursday, August 09, 2007

I've been monitoring the DasBlog developers discussion list the past few days and the topic of which AJAX platform to choose for use with DasBlog came up.

Why? Why does a blog site need AJAX? What is it that causes people these days to embrace AJAX - even just a little - for all sorts of causes that really don't need AJAX?

Don't get me wrong. I'm not saying that there is no need for AJAX or that you shouldn't use AJAX for creating "new and compelling" Web sites. Facebook is a good example of a site that uses AJAX in what I feel is a proper amount to make the user experience better, but it does not sell out in favor of doing AJAX for everything just because they can.

There are clearly places where I don't think the AJAX model provides a lot of benefit. For example, consider "live comment preview." You can see an example of it by leaving a comment on Scott's blog. Again why? Is the fact that I'm typing in a text box and likely reading what I'm typing insufficient? Do I really need to spend time formatting my comments with angle brackets and attributes? What benefit is there to me seeing in two places on the same screen the information that I'm typing?  Certainly there is a place for WYSIWYG editing on a web page, but I don't believe that comments are where it's at.

When you consider a blog, your objective as the consumer is to primarily read information and occasionally comment on information. There's really nothing in that interaction that benefits from AJAX. In this capacity a blog is a "read mostly" site. +1 if most of your readers use some sort of aggregator. If you're the blog owner you may be inclined to add posts via the web rather than a client such as Windows Live Writer or Word 2007. Even so, I firmly believe that AJAX has limited benefit to you as the primary - and oftentimes sole - contributor  to the blog. Can you really not live with a full page post back?

Now when you consider applications such as Outlook Web Access, Hotmail, Gmail, Google Reader, Virtual Earth, Google Maps, etc., a compelling case for AJAX is easily made. Certainly the focus of these applications benefits greatly from AJAX. But incorporating AJAX into a site just because its the cool Web 2.0 thing to be doing doesn't mean you should.

Technorati tags:
Thursday, August 09, 2007 1:11:54 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, August 08, 2007

To date, I've avoided social networking sites like My Space, twitter and, until recently, facebook. However, that all changed today with me joining facebook and incorporating iLike into my facebook page for the sole purpose of discovering new music.

Finding New Music

Today Dave and I were discussing the difficulty of finding new music that I like. My current usage pattern is that I use the iTunes store to find music, typically by browsing by genre, and then I head over to Zune Marketplace to actually purchase the music. But when I think socially about how I explore music, it's usually through friends, coworkers and customers that mention in passing some piece of music they have really enjoyed - and is typically the more accurate method of finding stuff I really like.

In both cases, my Zune Pass makes it really easy to sample the music and listen to it indefinitely on my Zune or purchase it outright if I want to keep it forever.

And, in both cases, neither is ideal. Maybe social networking in a Web 2.0 world is the right answer ...

Enter iLike

In the context of my conversation with Dave and one of the members of the Zune team, the subject of facebook and iLike came up. iLike is a social networking site that works with the published favorites of others to cross-sell recommendations on music for you. And it plugs directly into facebook. iLike links directly to the iTunes store so you can purchase the music directly and is fantastic if you're an avid purchaser of music from iTunes. Unfortunately, there's no support for Zune Marketplace ... but just the discovery of music relationships via artists, albums and songs is sufficient for me to find the music on Zune Marketplace and expand my personal library.

Join Me on facebook

So, come on over and join me on facebook! Make sure to add the iLike application to your facebook page and let's share our music preferences. I'm anxious to see what else is out there that I'm missing.

Technorati Tags: ,
Wednesday, August 08, 2007 4:55:16 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, August 01, 2007

image Either I'm an idiot, have reached the pinnacle of male pattern blindness or the designers of the URGE interface for Windows Media Player have made it next to impossible to stop the download process.

I started downloading a playlist and watched URGE and Windows Media Player respond to my request, filling my Music folder with more than 300 songs. About 50 songs into the process, I decided that I did not want to pollute my library with a ton of random songs and figured I'd just stop the downloading process. Except by now, I had navigated away from the downloading playlist and could not find anything in Windows Media Player or URGE to tell me what was downloading so I could cancel it. All I could do was watch my Music folder continue to fill up.

imageNavigating back to the playlist in URGE I found displays that the tracks are downloading - so it would seem that as long as I can remember where I started, I can find out what I'm bringing down ... but there is no option I can see to stop the process! Near as I can tell, I'm held hostage to the downloading process and now that it is (finally) finished, I can begin the process of cleaning up my Music folder.

Am I completely clueless and overlooking some simple option here?

image I have to give Zune props in this department, as marketplace provides an active downloads list and right-clicking on any active download provides a Cancel Download option. But try as I might, no amount of right-clicking, head banging, screaming or yelling could get URGE to stop the pollution of my Music folder.

Right now, my urge is to cancel URGE and continue to use Zune - as much as I hate the idea of yet-another-media-player on my machine.

Wednesday, August 01, 2007 10:05:00 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Thursday, July 26, 2007

I sat down last week to migrate a customer's ASMX service to WCF, and in the process discovered a problem with complex type serialization when WCF is configured to use the XmlSerializer and the complex type is in an XML namespace that is different from that of the service.

By default, Windows Communication Foundation uses the new DataContractSerializer. This new serializer is lean and mean. It is limited in its schema (it does not support attributes, for example), but delivers a considerable performance boost and greater ease of interoperability because of its simpler schema. The XmlSerializer, on the other hand, yields a ton of control over the schema, is the default serializer used by ASMX web services and is the one we want Windows Communication Foundation to use for compatibility with ASMX.

So let's take a look at .NET Framework 2.0s XmlSerializer behavior when given a complex type as might be generated by XSD.EXE or by an explicitly intentioned message designer. Here's a class, MyComplexType, decorated with the XmlRootAttribute and intended to place serialized instances of this class in the http://schemas.casadehambone.com/samples/2007/07 namespace:

[XmlRoot(Namespace="http://schemas.casadehambone.com/samples/2007/07")]
public class MyComplexType
{
    private string m_firstname;

    [XmlElement(ElementName="FirstName", Order=1)]
    public string FirstName
    {
        get { return m_firstname; }
        set { m_firstname = value; }
    }
}

Remember, the class MyComplexType is marked as being in the XML namespace http://schemas.casadehambone.com/samples/2007/07. That's going to be important in a bit.

Now, when MyComplexType is passed through the XmlSerializer, the following XML is generated:

<?xml version="1.0" encoding="utf-8"?>
<MyComplexType xmlns="http://schemas.casadehambone.com/samples/2007/07">
  <FirstName>Kevin</FirstName>
</MyComplexType>

Note the XML namespace declaration xmlns="http://schemas.casadehambone.com/samples/2007/07". This XML namespace declaration declares the default namespace for all unqualified elements within this type including the root element itself. Therefore, MyComplexType in the namespace http://schemas.casadehambone.com/samples/2007/07, as is the FirstName element. What we see is the intended and correct behavior.

Let's now shift our focus to the definition of the Web service. Here's an ASMX Web service that uses MyComplexType:

[WebService(Namespace="http://www.casadehambone.com/samples/2007/07")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class SomeService : System.Web.Services.WebService
{
    [WebMethod(MessageName = "Hello")]
    public string Hello(MyComplexType myType)
    {
        return string.Format("Hello, {0}", myType.FirstName);
    }
}

Take a close look at the WebServiceAttribute on the class declaration. It places the service in the XML namespace http://www.casadehambone.com/samples/2007/07, and is distinctly different than MyComplexType which resides in the XML namespace http://schemas.casadehambone.com/samples/2007/07. This, too, will become important in a bit.

If we examine the SOAP message sent by a Visual Studio 2005 generated proxy (i.e., Add Web Reference and referred to herein as an ASMX proxy), we can see exactly the impact our namespace declarations in code have on the serialized XML:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <Hello xmlns="http://www.casadehambone.com/samples/2007/07">
      <MyComplexType xmlns="http://schemas.casadehambone.com/samples/2007/07">
        <FirstName>Kevin</FirstName>
    </Hello>
  </soap:Body>
</soap:Envelope>

Take a moment to digest what is going on here. The Hello element uses a default namespace of http://www.casadehambone.com/samples/2007/07 which corresponds to the namespace specified in the WebServiceAttribute. Furthermore, this default namespace is to be inherited by all subsequent unqualified elements, including the root element itself until another default XML namespace is declared.

Next up is the serialization of MyComplexType. As previously discussed, MyComplexType uses a default namespace of http://schemas.casadehambone.com/samples/2007/07. And again, because the MyComplexType itself is unqualified, it too is in the namespace http://schemas.casadehambone.com/samples/2007/07.

Up to this point, all is right with the world and everything works the way we expect. Now let's throw Windows Communication Foundation into the mix by migrating this service via a couple of well-placed System.ServiceModel attributes. Seems simple enough, right?

Here's the same ASMX Web service updated to include the requisite System.ServiceModel attributes to expose it as a Windows Communication Foundation service and serialize in a way that is supposed to be compatible with ASMX:

[WebService(Namespace="http://www.casadehambone.com/samples/2007/07")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ServiceContract(Namespace="http://www.casadehambone.com/samples/2007/07")]
[XmlSerializerFormat]
public class SomeService : System.Web.Services.WebService
{
    [WebMethod(MessageName = "Hello")]
    [OperationContract(Action="http://www.casadehambone.com/samples/2007/07/Hello")]
    public string Hello(MyComplexType myType)
    {
        return string.Format("Hello, {0}", myType.FirstName);
    }
}

The ServiceContractAttribute, similar to the WebServiceAttribute, places the service in the same namespace as its ASMX counterpart, http://www.casadehambone.com/samples/2007/07.

The XmlSerializerFormatAttribute "instructs the Windows Communication Foundation (WCF) infrastructure to use the XmlSerializer instead of the XmlObjectSerializer." In other words, we're telling WCF that we want to serialize our classes in the same fashion as ASMX in order to maintain compatibility with our existing clients.

Last, but not least, is the OperationContractAttribute, similar to the WebMethodAttribute. By default, Windows Communication Foundation uses different action names than ASMX. Therefore to maintain compatibility with existing clients, we include the Action property and set it to the same value used by ASMX.

We're all set! We've exposed the same piece of ASMX code as a WCF service and have forced usage of the XmlSerializer to maintain serialization compatibility with existing clients.

And here is where the insidious problem rears its ugly head.

When the existing ASMX client calls the newly migrated WCF service, an exception is thrown and ... myType is null! What!? Huh? Excuse me? After repeatedly trying the client time and time again ... as if by magic I'm going to get a different result ... myType is null. Every time.

Knowing that this should work, I create a WCF client using SVCUTIL.EXE and call the exact same endpoint as that being used by the existing ASMX client and ... it works.

So for some reason WCF-to-WCF works fine for this service, but existing clients (i.e., ASMX-to-WCF) fail. Firing up tcpTrace and taking a look the XML sent by the WCF client reveals the problem. An insidious, subtle problem:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <
s:Body>
    <
Hello xmlns="http://www.casadehambone.com/samples/2007/07" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <
MyComplexType xmlns:a="http://schemas.casadehambone.com/samples/2007/07">
        <
a:FirstName>Kevin</a:FirstName>
      </
MyComplexType>
    </
Hello>
  </
s:Body>
</
s:Envelope>

Remember that we declared the namespace of the service to be http://www.casadehambone.com/2007/07 and the namespace of MyComplexType to be http://schemas.casadehambone.com/2007/07? It's vitally important to what's going on here, but that's not what the serialized XML shows.

The Hello element, declares a default namespace of http://www.casadehambone.com/samples/2007/07. The Hello element itself is unqualified and therefore is also in this namespace. So far, so good ... but take a very close look at the serialized version of MyComplexType in the WCF serialized version of the XML.

MyComplexType does not declare a default namespace. Instead, WCF has serialized MyComplexType and assigns the namespace http://schemas.casadehambone.com/samples/2007/07 to the prefix a. Normally this is not an issue ... all we need is semantic equivalence of the XML infoset and there is nothing wrong with using fully qualified QNames to achieve that goal. But look closely (very closely) at the serialized XML.

WCF proceeds to use the a: prefix for the serialized elements within MyComplexType but neglects to associate the prefix a: to MyComplexType! The result is that MyComplexType, being unqualified and not declaring its own default namespace, inherits the namespace from its parent! MyComplexType is now in the namespace http://www.casadehambone.com/samples/2007/07, the namespace of the service not the namespace we specified for the type!

If we had originally placed MyComplexType in the same namespace as the service (i.e., if both were in the namespace http://www.casadehambone.com/samples/2007/07) we would never see this problem. Both ASMX and WCF would generate semantically equivalent XML.

If we used simple parameters to our WebMethod/OperationContract (i.e., public string Hello(string FirstName)) we would never see this problem.

This problem only surfaces with WCF when the complex type is placed in a namespace different than that of the service.

So what are we to do?

Well, our guidance on MSDN for Migrating ASP.NET Web Services to WCF works, but is terribly more complex than adding three additional attributes to your existing ASMX code. In fact, our guidance has you reverse engineer the service contract and data contract using SVCUTIL.EXE (as if you were building a client) and then re-implement a brand new service using the interfaces and classes created by SVCUTIL.EXE. It works because the auto generated service contract, data contract and message contract do result in semantically equivalent XML when the message is serialized, but WCF must use a message contract to get the work done. And a message contract is tantamount to saying, "You know what ... you don't know how to serialize things properly, let me tell you exactly how I want it done." Not surprisingly, this is a very true statement about this condition in WCF, and considerably raises the complexity bar. I shouldn't have to rely upon a MessageContract to get this done.

A second option was offered up by my esteemed colleague, Dino Chiesa. Dino created a custom ServiceHost that explicitly looks for complex types with an XmlTypeAttribute or XmlRootAttribute and a namespace that disagrees with the service's namespace. When a mismatch is found, Dino's custom ServiceHost changes the MessageParts to properly align the namespace with that of the complex type. Furthermore, because this is done before any instances of the service are ever created, you also get a proper schema in the WSDL!

In Dino's words, his solution is only 35 lines of boilerplate code once you remove the comments, white space and logging - and is completely reusable, whereas our MSDN guidance requires you to re-implement each and every service you have to get compatibility. You can use his custom ServiceHost with IIS-hosted services and migrate your ASMX services to WCF while maintaining compatibility with existing clients.

What surprises me is that I've not heard anyone bring this up before. Is no one migrating at all? Is no one migrating services with complex types with their own namespace declarations?

What do you have to say? Have you run into this issue in migrating any of your complex ASMX services to WCF? How did you deal with the problem?

Technorati Tags: , ,
Thursday, July 26, 2007 8:08:07 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Saturday, July 21, 2007

Harry Potter and the Deathly Hallows (Book 7)A few weeks back I was deciding if I wanted to join the masses to get my copy of Harry Potter and the Deathly Hallows on release day or just pre-order it from amazon.com and wait for it to arrive. Amazon sent me a marketing e-mail, claiming that if I pre-ordered by noon the day of the e-mail's arrival, I could receive the book at half-price and they would guarantee release day delivery or my purchase was free.

Hmm. Half price. Release day deliver. I was willing to pay full price and wait a few days past release to get it. Sold! And at 3:30PM today, UPS arrived with an Amazon custom-branded Harry Potter and Deathly Hallows box clearly marked in red not to be opened or delivered before July 21, 2007.

Amazon continues to impress and continues to receive my business. Great job, Amazon!

Technorati Tags: ,

Saturday, July 21, 2007 2:54:56 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, July 04, 2007

I was doing some Windows Communication Foundation development today and finally grew tried of receiving AddressAccessDeniedException when running my service host as a non-Administrator.

When you hit this exception, Visual Studio 2005 is kind enough to point you to Configuring HTTP and HTTPS on MSDN. If you read close enough, you'll find the nugget that includes the updated syntax when using Windows Vista buried as two lines:

If you are running on Windows Vista, you can use the Netsh.exe tool instead. The following shows an example of using this command.

netsh http add urlacl url=http://+:80/MyUri user=DOMAIN\user

The much improved netsh.exe on Vista incorporates the features previously found in httpcfg.exe. Furthermore, where httpcfg.exe really sucked, netsh really shines. Consider that httpcfg.exe required you to be familiar not only with the obtuse SDDL string format, but you also had to uncover the SID for the account to which you wanted to grant permissions:

httpcfg add urlacl url=http://+:80/MyUri /a D:(A;;GX;;;S-1-5-21-1144070942-1563683482-3278297161-1114)

Not the most friendly command line in the world. Dominick Baier has a nice utility, HttpCfgAcl.zip, that will spit out the necessary SDDL with the included SID. But true joy is found with netsh in Windows Vista. The same URL ACL entered above with httpcfg.exe is expressed much more cleanly via netsh.exe as:

netsh http add urlacl url=http://+:80/MyUri user=Kevin

No more messy SDDL. No having to translate account names to SIDs. Just a nice clean syntax netsh.exe syntax.

This just barely scratches the surface of what you can accomplish with netsh. Also check out Scott's article on using netsh as a better ipconfig.

Technorati tags: , ,
Wednesday, July 04, 2007 4:18:02 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

It's been a nutty few months here at Casa dé Hambone, personally and professionally.

Personally

We had a 40' tree removed from the back yard, the stump ground out and the electric to the garage severed in multiple places in the process. I've finally dug a 3" wide, 1' deep and 50' long trench from the house to the garage in preparation of running all new electrical ... now to find the time to finish!

We've set up a 3,600+ gallon, 15'x42" Intex above-ground pool. Along with that I installed a new GFCI outlet - which included pulling new wire - a digital timer and a salt water pool system - a fancy term for a chlorine generator. I must say, I was skeptical about the chlorine generator but we have been enjoying clear, clean pool water for some time now and enjoying the pool.

We adopted Sonata, a 9 week old mixed pit bull terrier pup from Heartland Animal Shelter. She's been a pure joy. The kids are thrilled to have a family pet. We invested a good deal of time in watching Cesar Milan: The Dog Whisperer and have learned the difference between leadership training and obedience training. We've also invested 8 weeks in basic puppy training at our local PetSmart that, combined with consistent effort, has provided great return.

In May, my grandmother passed away and we spent two weeks in California with family. This may sound odd to some, but her funeral ceremony was a blessed, joyous event. It was truly inspiring and, while I'm saddened at the loss of my grandmother, I have a distinct peace in knowing her own joy at truly being home with our Lord and Savior.

In June we celebrated both my daughter's and my birthdays. She's getting more beautiful each day and I get more gray each day. Why can't I get more beautiful instead?

Professionally

At Microsoft, we closed out fiscal year 2007 at the end of June and have already started our planning for fiscal year 2008. It seems that the groundwork is laid to have our commitments in place by the middle of August. To some, this may not seem like a big deal but in years past we've waited as long as September - sometimes October - before being locked on what it is we're being measured on for the course of the year. Suffice to say, loosing an entire quarter that would otherwise contribute to delivering results sucks. I'm encouraged to see the faster start this year.

I delivered a talk at Tech*Ed 2007 on integrating information cards and Windows CardSpace. Since attending my first Tech*Ed some 13+ years ago, I thought how cool it'd be to speak at the conference. The Connected Systems Division provided me the opportunity this year and I had a blast.

Why Software Sucks...and What You Can Do About ItI delivered an introductory talk on information cards and Windows CardSpace to Dave Platt's programming class at Harvard University Extension. Hard to believe that I got to walk the halls of and lecture to students at Harvard after not completing college myself. Dave is an awesome guy and I highly recommend that you read his book, Why Software Sucks and visit his web site, Rolling Thunder Computing.

The Move to webhost4life

In the process of all the above, we've suffered more than our fair share of power outages - both self-induced and nature-induced - have seen another computer failure for the self-hosted version of casadehambone.com and, as a result, I've relocated www.casadehambone.com to webhost4life.

I'm thrilled to see that webhost4life supports .NET Framework 3.0 and ASP.NET 2.0 applications running in full trust. I've been able to move my entire instance of DasBlog over without any issues by simply zipping up the existing site, uploading to webhost4life and setting some DasBlog-specific permissions. Furthermore, they will even install my existing SSL certificate enabling me to provide continued access using information cards.

The upside for me is no longer worrying about the status of the site on my end. I get to offload bandwidth, backup, hardware maintenance, etc., to someone else. I also get to turn off one more machine - a savings in power consumption, heat generation and space.

So, if you're reading this then you're receiving the feed via the new webhost4life-hosted version of casadehambone.com! I hope you enjoy an increase in availability of the site.

What's Next?

I plan to upgrade to the latest release of DasBlog - the last release that targets .NET Framework 1.1 in the near future, but doing so means redoing the information card work. On the up side, I've learned  a lot about information cards and Windows CardSpace since my early integration work and hope to provide a better overall user experience.

Oh look ... the dog made another mess in the house.

Wednesday, July 04, 2007 7:40:29 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [2]  |