Scott Hanselman

A multi-request-safe ViewState Persister

June 23, 2004 Comment on this post [7] Posted in ASP.NET | ViewState
Sponsored By

Mark Miller has posted his code for a ViewStatePersister using the "common sense but not obvious" GUID technique that was outlined previously by Scott Mitchell and myself.

He stores a GUID in the ViewState hidden field, and sticks the bloated ViewState in a temp file on the server.  It doesn't solve the problem when running multiple web servers while using stateless balancing (meaning: NOT using sticky sessions/node affinity) but it's the most elegant and complete solution I've seen yet and should work great on a single web server. 

A few questions I have though:

  • When do the files get cleaned up and how often? Do you clean up old ones in a background thread within ASP.NET or a separate Windows Service?  Thought: I wonder if you could delete them after immediately after the Load?  You wouldn't be able to RE-post data, but it'd be cleaner, no?
  • GUID generation is very expensive, and can really slow you down under load.  I wonder if it would be faster/easier to have a single long and use InterlockedIncrement or  InterlockedIncrement64 to safely increase the value on each call until it overflows and you start again at 0.

Many thanks to Mark for sharing!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

How to transfer/move all your Email from Hotmail (or Yahoo!) to Gmail

June 23, 2004 Comment on this post [29] Posted in Bugs
Sponsored By
If you enjoyed this post, or this blog, please make a secure tax-deductable donation to the American Diabetes Association. Please read my personal story about life as a diabetic and donate today.

I was lucky today and a friend offered me a Gmail invite (Gmail being Google's 1 gig Free Email BETA if you've been living in a cave without wireless).  I don't need a Gmail account but the wife digs web-based email and suffers with a 1 meg Hotmail account.  She's constantly deleting emails trying to stay under the limit.  (and she's too cheap to pay for more storage :) )

But, how to move all her Hotmail stuff (several hundred emails) over to Gmail?  If I can't move them, she'll hardly find the service useful. 

So...

  • Download Eudora, and install the Sponsored version. 
    • Why Eudora and not Outlook or Thunderbird?  Because you'll want to REDIRECT the emails that come in from Hotmail, NOT FORWARD THEM.  If you just Forward them, they'll all look like they came from you!  You want to hang on to the FROM and the TO.  Eudora is the easiest and most available email client to do this.  (Yes, I was surprised Thunderbird doesn't - it's been a bug for a while)
  • Download Hotmail Popper.
    UPDATEIf you have Yahoo! then you can use YPOPs which does the same thing!   
    • This little gem sits in your tray and creates a localhost POP server that bridges to your Hotmail account. 
      Note: Make sure you check Retrieve messages from folders other than Inbox or you won't get all your Hotmail!
  • Create a REDIRECT Filter that grabs all incoming mail.
    • Make a filter like this.  Mine says match all mail the DOESN'T contain this nonsense word (which is all mail) and REDIRECTS it to the wife's gmail.com account. 
      Note: Turn off IMMEDIATE SEND in Eudora, we'll want to QUEUE the mails, as we need to change the outgoing SMTP (can't be Hotmail!)
  • Get the Mail.
    • Now, in Eudora, make and account like this:
    • Important: Make sure you check LEAVE MAIL ON SERVER under "Incoming Mail" so you don't delete all the messages in your Hotmail Account.
    • At this point, you should have downloaded all the email from Hotmail, and all the same messages should be in the Eudora Outbox ready to send.
    • Remember, we have to Redirect the emails, so we'll need access to an SMTP server that supports REDIRECTS.  Make sure you have one, or know of one you can use.  I have my hanselman.com one, but it's SMTP (outgoing mail) requires Authentication as all good SMTP servers should.
  • Send (Redirect) the Mail to Gmail.
    • Important: First, change login name in the Checking Mail option (see above) to the name required for your Outgoing SMTP server.  That's the name that is used when sending!  It WILL be different than your Hotmail name.
    • TIP: Have any Gmail Filters that you might wanted applied to incoming messages setup BEFORE you do the big "export/import."  Otherwise you'll have to Search and Apply Label later.
    • Now, in the Sending Mail option set your return mail address to your new Gmail.com account.  (That way your Redirects will list you as the "On Behalf Of" name)
    • Enter your SMTP Server, and select Immediate Send.
    • Now, from the Eudora File Menu, select "Send Queued Messages" - this will send them with the new SMTP authentication info as REDIRECTS.
  • Enjoy your new, fully populated - from Hotmail - Gmail account! Spread the word!
    • Optionally: Uninstall Eudora, Hotmail Popper, and instruct Eudora to delete the local email store.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Be aware of your DLLs and who's loading them - know about assembly binding redirects

June 23, 2004 Comment on this post [0] Posted in ASP.NET | XML | Bugs | Tools
Sponsored By

When it rains it pours.  Twice today folks came looking when unexpected behaviors occured after an SDK upgrade.

If you're using a versioning scheme, always ask yourself, what version of my assembly has been loaded into this AppDomain?  It's even more important to be aware (and not to Program By Coincidence) when using the GAC.

Digging into the problem showed that the wrong version was being loaded - an older version from the GAC due to an incorrect bindingRedirect.

A few tools to be aware of and WHAT they tell you about Assembly Binding:

  • Binding before it happens: ILDASM or Reflector will tell you what your assembly wants (what it was compiled against)
  • Binding as it happens: Fusion (the Assembly Binding Log Viewer) will show you all assembly binds if you set the HKLM\Software\Microsoft\Fusion\ForceLog registry value to 1
  • Binding after it happens: Process Explorer will tell you what DLL (assembly) is loaded in memory and from where it came.

In this case, a little command line showed me:

C:\>gacutil /l | find /i "Corillian" | more
   <snip>
Corillian.Thingie.Whatzit, Version=3.1.0.39, Culture=neutral, PublicKeyToken=xx
Corillian.Thingie.Whatzit, Version=3.1.1.31, Culture=neutral, PublicKeyToken=xx

Ah! There's an older version in the GAC, probably supporting another Web on this box.  Our ASP.NET site was compiled against this (says Reflector) and we confirm the wrong one was loaded with Process Explorer. But, we need a bug fix from the new version and can't recompile, so, in our Web.config we added:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
   <dependentAssembly>
    <assemblyIdentity name="Corillian.Thingie.Whatzit"
     publicKeyToken="xx"
     culture="neutral" />
    <bindingRedirect oldVersion="3.1.0.39" newVersion="3.1.1.31" />
   </dependentAssembly>
  </assemblyBinding>
</runtime>

Now when our ASP.NET apps asks for 3.1.0.39, instead it gets 3.1.1.31.  Note that our assembly must be strongly-named for this to work.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Using NUnit and a better way to Unit Test with External File Dependancies

June 23, 2004 Comment on this post [2] Posted in NUnit
Sponsored By

Great stuff on using NUnit in conjunction with external files from Patrick Cauldwell.  It's one of those "Doh!" things that I've always MEANT to do, but somehow ended up using Pre- and Post-Build events instead.  I MUCH prefer Patrick's method.  It's much cleaner and it allows the once-external file to LIVE with the test.

        [SetUp] public void SetUp()
        {
            Assembly a = Assembly.GetExecutingAssembly();
            using (Stream s = a.GetManifestResourceStream("MyNameSpace.something.txt"))
            {
                using (StreamReader sr = new StreamReader(s))
                {
                    using (StreamWriter sw = File.CreateText(webConfigPath))
                    {
                        sw.Write(sr.ReadToEnd());
                        sw.Flush();
                    }
                }
            }
        }

        [TearDown] public void TearDown()
        {
            if(File.Exists(webConfigPath))
            {
                File.Delete(webConfigPath);
            }
        }

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Forcing NAnt to build and run with a specific version of the .NET Framework

June 23, 2004 Comment on this post [0] Posted in Nant | XML
Sponsored By

If you're not careful, and you have both versions of the .NET Framework on your box (1.0 and 1.1) NAnt will build your stuff using .NET 1.0.  Whether that's what you want or not, it's important to be explicit.

There's two ways:

  • Add <property name="nant.settings.currentframework" value="net-1.1"/> to your .build file(s).

or, to make the change to .NET 1.1 as the default, look in the NAnt.exe.config file in the same directory as NAnt.exe.

In this XML config file, in /configuration/nant/framework/platform[@default] you'll want to set that default attribute to "net-1.1" like this.  Note: The ID "net-1.1" corresponds to a named <framework> section called "net-1.1" further down in the file that gives NAnt all the info it needs to build on that version.  NAnt can also be used to build Mono, at least as of version 0.28 of Mono.

<configuration>
     ...snip...
  <nant>
        <frameworks>
            <platform name="win32" default="net-1.1">

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.