Sunday, April 3, 2011

Cookieless Session State in ASP.NET without nasty URLs

Some of you have probably heard about the EU proposal that plans to end the internet as we know it on May 25th 2011. If you haven’t heard of it, David Naylor has made a nice little example of it’s consequences here. In essence most sites that use cookies will have to ask visitors to opt-in for every single cookie before using it. I’m very  much in favor of online privacy – yet it seems to me that this is a very poorly thought through directive. First of all, most cookies server 1 of 2 purposes:

  • Help web sites recognize visitors in order to provide them with the best possible service. Much like when I walk into my local barbershop and the barber recognizes me and knows exactly how I prefer him to cut my hair (the little I have left after reading crazy directives) – and which subjects I want to small talk about.
  • Visitor tracking in order to do statistics the site owners can use to improve the web site with. Again – it’s not all that different from when a grocery store owner thinks “wow – 10 customers this last week has asked me for low-fat milk. Perhaps I should start to carry that product here”.

I have no problem with both of the above scenarios – they fall into what I call good service and help enhance my online experience.
Another problem is that I generally dislike when legal stuff comes in the way for the best technical solution to a problem. Laws should describe the concept of what they are outlawing – not specific technical architectures such as cookies…But before I digress any further into political territory I’ll get right back on track.

Many ASP.NET developers rely on the Session State mechanism to store user relevant data within a visit, that can improve the user experience – for instance with personalization, prefilled forms, and so on. Unfortunately the Session state relies on a unique session key being stored in a local cookie in order to have a unique way to identify the same visitor throughout a visit. It actually comes with a built-in switch to make it stop using cookies – but unfortunately the solution looks rather ugly – it changes all the URLs on the site to contain a Guid and thereby track the visitor using the Guid. I, for one, am rather fond of clean and pretty friendly urls – so that’s no good. So – I started thinking…Many years ago I worked for a company that built a statistics tool. It was pretty unobtrusive and we didn’t use cookies. Instead we just tracked the source IP – and checked for repeated requests with a 10 minutes time-out. Sure, it wasn’t bullet-proof, but it actually worked surprisingly well. And in those cases where it didn’t work? Well – it was just 1 statistical entry out of many. It’s not like we used it to authorize access to the nuclear football, right?! Now, I thought that if we combine all the static information we get in the HTTP Request like IP, Accept Languages, Accept Types, User Agent and so on, smash it all together and take a fingerprint of it – we might end up with something that can almost be used as a session id. Consider: What are the odds that you’ll get 2 different visitors using the exact same configuration, coming from the exact IP on your site within the 20 minutes default time-out??
Of course it turns out I wasn’t the first to think this thought. In fact the clever people at the Electronic Frontier Foundation (EFF) has for some time been running a little example site that calculates those exact odds – just to prove that Privacy online isn’t solved by simply outlawing cookies.

So – I decided to put the thoughts into code. The code consist of 2 parts. First part is an extension method for the HttpRequest class, called “GetUniqueFingerprint()” which will return a MD5 Hash fingerprint.

using System;



using System.Collections.Generic;



using System.Linq;



using System.Web;



using System.Text;



using System.Security.Cryptography;



 



namespace AllanTech.NoCookie



{



    public static class NoCookies



    {



 



        static private string GetMd5Sum(string s)



        {



            Encoder enc = System.Text.Encoding.Unicode.GetEncoder();



            byte[] text = new byte[s.Length * 2];



            enc.GetBytes(s.ToCharArray(), 0, s.Length, text, 0, true);



            MD5 md5 = new MD5CryptoServiceProvider();



            byte[] result = md5.ComputeHash(text);



            StringBuilder sb = new StringBuilder();



            for (int i=0; i<result.Length; i++)



            {



                sb.Append(result[i].ToString("X2"));



            }



            return sb.ToString();



        }



 



        public static string GetUnqiueFingerprint(this HttpRequest Request)



        {



            string source=



                string.Join(",", Request.AcceptTypes)+";"+



                string.Join(",", Request.UserLanguages)+";"+



                Request.UserHostAddress+";"+



                Request.UserAgent;



            return GetMd5Sum(source);



        }



    }



}






Second part is a replacement for the ASP.NET SessionIDManager. This is the mechanism that uniquely identifies the visitor – either by a cookie or url – and by replacing it we can make it use our new UniqueFingerprint method instead. It’s really simple – just implement the ISessionIDManager and you’re good to go:





using System;



using System.Collections.Generic;



using System.Linq;



using System.Web;



using System.Web.SessionState;



 



namespace AllanTech.NoCookie



{



 



    public class CookielessIDManager : ISessionIDManager



    {



        public CookielessIDManager() { }



 



        #region ISessionIDManager Members



 



        public string CreateSessionID(HttpContext context)



        {



            return context.Request.GetUnqiueFingerprint();



        }



 



        public string GetSessionID(HttpContext context)



        {



            return context.Request.GetUnqiueFingerprint();



        }



 



        public void Initialize()



        {



            



        }



 



        public bool InitializeRequest(HttpContext context, bool suppressAutoDetectRedirect, out bool supportSessionIDReissue)



        {



            supportSessionIDReissue=true;



            return context.Response.IsRequestBeingRedirected;



        }



 



        public void RemoveSessionID(HttpContext context)



        {



        }



 



        public void SaveSessionID(HttpContext context, string id, out bool redirected, out bool cookieAdded)



        {



            redirected=false;



            cookieAdded=false;



        }



 



        public bool Validate(string id)



        {



            return true;



        }



 



        #endregion



    }



}




Finally, all I have to do is to change the configuration (web.config) to use my CookielessIDManager instead of the default:



<sessionState mode="InProc" sessionIDManagerType="AllanTech.NoCookie.CookielessIDManager,AllanTech.NoCookie" … /> 



Enjoy a site with 1 less cookie!

Monday, August 2, 2010

A simple, little web load tool

There are many ways of doing performance testing of web applications. In the good ol’ days I remember starting up Microsofts Application Center Test (ACT) and recording some vbscripts that could later be executed. Nowadays ACT is a lot sexier – but now it comes with Visual Studio 2010 but unfortunately only in Ultimate edition. I tried to persuade my wife to spend the $11000 on the ultimate edition – but she failed to see why this was more important than buying her a car.

Another good option is to use WebLoad. It’s a neat tool – and even if you buy it (to actually get a compiled and running version instead of the do-it-yourself-open-source) it still comes at a more decent price point. I recently played around with it – and it does solve a lot of your performance testing needs – but it’s almost a bit too much overkill for my need (which is essentially to find out how many request/s a web site can handle). I also didn’t like that it hijacked all my browsers and forced them to go through a proxy (in order for it to record what was going on) – and then failing to reset the proxy selection afterwards.

In the end I decided to spend the 30 min it would take to do a simple little performance tester of my own – that does exactly what I want it to.

I came up with AWebLoadTesting which is a compact and ultra-simple console app. It takes an input file which is essentially a text file with a list of urls to visit for each visitor during the test, an output filename – in which it will put a csv file with saved statistics – and that’s about it. If you need to you can also specify a hostname to run the test against – and even a custom UserAgent for the requests.

image

When it starts you have 0 visitors active. Then, by pressing “+” you can add visitors one at a time – and by pressing “1” and “5” you can add chunks of 10 or 50 visitors at a time. Each visitor is started in its own thread and will continuously go through the urls from the input file again and again.

“u” updates your view, “r” resets the counters", “s” saves the current data to the output file, “-“ removes a visitor” and of course “q” quits.

You’ll constantly be presented with the measured numbers: Time measured (s), Requests / s, Visitor count, Max load time, average load time and min. load time. On top of that it will show you a prioritized list of which urls are the slowest to return. That’s it.

The screenshot above is a test against a local EPiServer CMS 6.0 web site on my laptop, running with ASP.NET caching turned on (Set cache-expiration to 1h in episerver.config, site settings).

Download the binary here and the entire project here. Use AS-IS, LGPL 2.0, Quick&Dirty.

Monday, May 17, 2010

And a (non-virtual) role change

May 1st I arrived back in Denmark after spending a year in the US assisting with assembling and training the GREAT team that we have there now as well as working with some truly skilled and passionate partners (you know who you are). I must say it’s been a great learning experience as well as a very exciting time – both for EPiServer but also for me personally.

Now, that I’m back in the old world again it seemed like a good time to try a new angle at producing great software – and as luck would have it I was offered to try on the shoes as product manager. Even though I’ve always had a deep passion for coding I’d love a chance to really influence the future of creating great web sites in a way that only a product manager at EPiServer can do it.

I believe that the most important job for any software product company is to create software that solves real problems that people in their markets have. This is the key factor that more than anything should be driving both the development and sales process – solving real problems for real people. And of course solving the problems in a carefully designed and planned manner so the solutions adapts to the users needs and skills – and not the other way around. Too many times have I seen countless examples of technology and features in various products (in all industries) that are there for no other other reason than adding a feature – but not solving any real problems. Flashy as some of it may seem it’s still essentially useless. The consequence: development time that could have been spend solving problems wasted, and users confused with features that doesn’t make sense.

Luckily EPiServers history shows that we have been very successful in solving real problems. And I believe that’s why so many web sites, editors, developers and marketing people use our entire product portfolio as their platform of choice today. But of course we can still do even better. Especially with YOUR help. I want to learn how you use EPiServer CMS. And even if you don’t use it – tell me how you manage your online content and which problems we could solve for you.

Wednesday, May 5, 2010

Yo, Halo Reach Beta Peeps

A long time ago I wrote about shotcodes and for that purpose I even put a shotcode on the web site linking to this web site. It would finally seem like I now get my 15 sec of fame, since Halo Reach supposedly have used a graphic with some similarity to my shotcode in the game (see the computer terminal to the right here). After Zoidberg25 “cracked” this in the Bungie forums I’ve gotten a certain amount of visitors looking through my blog for hidden clues – or maybe even an ARG.

Although I appreciate all traffic and every single visitor to my blog is very welcome, I feel that I should probably come clean. I can deny any and all rumors that this blog is part of an intricate scheme to hide secret game codes or Easter eggs. Or maybe not. Feel free to read through every single post and comment – look for hidden codes and clues (remember that the classical Substitution Cipher is always a popular way to hide secret stuff in plain view. While you are trying to crack this one, feel free to click the links and read what my sponsors have to say. And if the adds generate enough revenue I might even buy that silly game of yours and see what all the fuzz is about (if I actually manage to clean the dust off my Xbox 360).

Sunday, February 14, 2010

Awesome nostalgia trip!

Do you remember the good old Sierra Quest games? Well – I do. I loved those games. Especially police quest I->IV which could run on my dad’s old PC. I’d play them again and again during the late 80’ies / early 90’ies and to this day I hold them responsible for me learning english (although my english teacher in primary school did give it a nice try as well). Of course, Space Quest, Kings Quest and the immortal Leisure Suit Larry were classics I played as well.

Anyway, yesterday sitting in Philadelphia airport waiting for my flight back to civilization (Chicago) made me think: If only someone would port those old abandon-ware classics so I could run them on my iPhone. And guess what – Martin Kool has. And not just to the iPhone – they have been converted to javascript and can run on pretty much any modern browser. And now they even have multiplayer mode.

Check out the great web site here – but be prepared that it will take you hours before you can once again escape from nostalgia land.

Martin: I’m a great fan of your work. Keep it up – can’t wait to see more classics out there.

Wednesday, December 23, 2009

Visual Studio 2008: Application Cannot Start

 

I got this annoying error, every time I tried to run my VS2008 SP1 in Administrator mode (which is needed to avoid the “Failed to map the path '/'.” when running an EPiServer site in visual studios web server). Some google searches brought to outdated microsoft material – but luckily also to Alex Riley’s helpful post: https://www.21concepts.com/Blog/EntryId/10/Visual-Studio-2005-2008-The-application-cannot-start.aspx.

On my win7 x64, it turned out (thanks procmon) that my visual studio was looking for C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\dte80a.olb – and once I copied that from C:\Program Files (x86)\Common Files\microsoft shared\MSEnv all was well.

Sunday, November 1, 2009

QuickWatch Gadget for EPiServer CMS 6 Gadget Contest

imageI just published my contribution to the EPiServer CMS 6 Gadget Contest on EPiServer World.
This time I have been playing around with dynamic compilation and running code on the fly in Web Applications.

Download the Gadget and check out the source here:

 http://world.episerver.com/Blogs/Allan-Thran/Dates/2009/11/QuickWatch-Gadget/

Thursday, September 3, 2009

HTTP Error 500.19 – Internal Server Error

A couple of times I have now run into this wonderful error after setting up a new EPiServer CMS site on a newly installed machine. However, I don’t think it’s specific to EPiServer CMS – but can occur in any asp.net application. The error message looks like this:

The requested page cannot be accessed because the related configuration data for the page is invalid.

As with many other microsoft errors, this is completely misleading (unless you’ve been messing up your configuration data – but this is a newly installed site).

The error message tries to clarify itself further:

Module
IIS Web Core

Notification
BeginRequest

Handler
Not yet determined

Error Code
0x80070021

Config Error
This configuration section cannot be used at this path. This happens when the section is locked at a parent level. Locking is either by default (overrideModeDefault="Deny"), or set explicitly by a location tag with overrideMode="Deny" or the legacy allowOverride="false".

Config File
\\?\C:\EPiServer\Sites\MyEPiServerSite3\web.config

 

By now, you are probably half way into your web.config, and trying to remember where that mystical machine.config is located. You might even have started to go through all directories on your machine in the search for another web.config thats somehome conflicting. Stop looking. It’s not conflicting. And relax – you didn’t do anything wrong…yet.

One of 2 things have likely happened:

1) IIS was installed after ASP.NET, and it’s not really sure what to do with ASP.NET code. Solution: In a command prompt run aspnet_regiis. It’s typically found in “%windows%\Microsoft.Net\Framework\v2.0.50727\aspnet_regiis –i”. Note that you need to run it as Administrator on Vista and Windows 7. In fact, running this can be a cure for many initial web server errors on newly installed asp.net applications.

2) You are running Windows 7 or Windows Server 2008 and you selected the default install of IIS7.5. For reasons known only to Microsoft, they decided that ASP.NET shouldn’t be included in a default installation. My personal theory is that the guy who made that wise call is probably the same guy who decided to remove the ability to drag files onto a command-prompt in Vista. And before that was the mastermind behind the “Copy File” feature in any earlier version of Windows. But I digress :-) Solution in this case is easy – Open Control Panel | Programs | Turn Windows Features on and off, find IIS and enable ASP.NET:

image

Hit “Ok”, wait for half an hour and then see your web application spring to life. Enjoy!

Sunday, August 2, 2009

Guest Post: Конвертирование FB2 в PDF для Sony Reader PRS-505

image

Я - счастливый обладатель Sony Reader PRS-505!
Однако взявшись за чтение книг на русском языке, я обнаружила, что формат, в котором можно скачать большинство книг на русском в интернете FB2, не поддерживается моим Reader. Возникла проблема - как сконвертировать FB2 в один из форматов, поддерживаемых Sony Reader (например, PDF).
Найденная в интернете веб страничка http://fb2pdf.com/ , которая позволяет сконвертировать формат в PDF, к сожалению, сработала только в первый раз. В остальных случаях конвертация занимала слишком долгое время.
К счастью, мой муж - волшебник, и по совместительству программист, создал программу, которая позволяет сконвертировать FB2 в PDF в считанные секунды, и он безвозмедно предлагает ее всем любителям (электронных) книг на русском языке.
Загрузить программу можно здесь.

New Tool: Convert .FB2 files to PDF

ereader

It all started a couple of months ago when my wife, @othraen, got her Sony eReader. She loves it, and reads a couple of books a week on it. I can definitely see why she likes it – it’s slick, simple, and very pleasant to read on. Great toy, if you like books!

Anyway, with the speed she’s reading, not even the 5000000000000000 (or whatever count they reached now) free titles at Google Books is enough, and she’s started looking online for public domain Russian language books (most Russian is like Greek to me, but she likes it :-) ). As it turns out most of the Russian e-books online are in the FictionBook 2 format (.FB2). It’s an open XML format, probably defined by a league of Russian e-book publishers or so – it doesn’t seem to be all that popular in the rest of the world.

As you might imagine, the friendly people at Sony didn’t take this into consideration when planning on which formats to use in the eReader, so it is not supported. However, our friend, good old reliable PDFs are of course supported. It didn’t take many Google searches to find the fb2pdf.com website – a site devoted to converting fb2 files to PDF. It worked great on the first book….And on the second book. But later on, several of the books she tried to convert wouldn’t work. It would just freeze up and we could wait for ever and ever. As it so often happens, this resulted in the statement I fear so much “Honey, can’t you spend a little less time playing around with that programming stuff and a little more helping me get this book I want to read on my ereader??!” (yes, one of those questions where there’s only one right answer). In this case it would have made sense to simply drop a mail to the owners of the before mentioned website, asking them to fix whatever bug that caused the conversion to fail – but I was determined not to let this be the first time I give in to common sense :-)

image Instead this was a perfect opportunity to take a closer look at FB2, PDFs, the iTextSharp library, SharpZipLib and ClickOnce deployment. At the same time, I’d get to program in my spare time – and with a perfect excuse – helping her :-)

It didn’t take much more than a couple of hours before I had a working windows application, that can load .fb2 files (or zip-files containing 1 .fb2 file), correct / change their Author / Title (since the ereader doesn’t seem to support Cyrillic characters in the title browsing menu), and convert into a PDF. It’s a ClickOnce application, which means you can install it directly from it’s online source – and it will automatically get updated if I upload a new version. The only tricky thing in developing it was actually embedding a font to show the Cyrillic Unicode characters that most Russian books are comprised of.

[UPDATE 2009-12-20] I finally found some time to fix a few bugs and add two new check-boxes: "Optimize for Sony Reader" and "Optimize for Kindle". Right now, all they do is to optimize page-sizes, so it should work better on the respective devices - but in the future they might also adjust font, font-sizes, etc. Let me know how well it works - I don't have a kindle, so I can't test it myself. Update should install itself.

Install the FB2 to PDF Converter tool from here.

Sunday, June 21, 2009

Trends in Web Content Management

After a couple of weeks of attending various web content management conferences (GilbaneSF and Web Content in Chicago) and talking to a lot of people more clever than I, I figured that a summarizing blog post might be in order. These are some of the trends I spotted.

 

Social

Facebook, Twitter, Flickr have paved the way – now everybody wants user generated content. It seems as if most companies has figured out that visitors that contribute with content are dedicated visitors – and who wouldn’t want those?! Most CMS vendors has forums / blog functionality built-in – and a handful have gone all the way with full-sized communities containing clubs, my-page, videos, friends, social graphs, you name it (including EPiServer). A lot of the stuff isn’t new – forums and public profiles were common even during those delightful years of BBS’in in the eighties and early nineties. And during the Web 2.0 era a few years ago it boomed. It’s first now, however, that people are really considering when to use which features – and when not to use it. Perhaps it is really time to start use this technology not just “because we can” but “because it makes sense”. This might just be when Web 2.0 turns profitable.

 

Personalization

Personalization has been hot for a couple of years now. Pioneered by companies such as Amazon, Netflix, etc. companies are now starting to see real business value in personalizing their content. The term is used to cover a lot of different technologies and usages however. Everything from changing the language of the website to automatically suggesting products that the current user is interested in – is some kind of personalization. Even silly things such as letting the user customize the style or background color of the website is getting popular.

Again Facebook has turned out to be somewhat of a thought leader – adds shown there are totally personalized to your characteristics increasing the possibility of a click/purchase.

Most CMS vendors have some sort of way to enable simple personalization – like the ability to save key/value fields about each visitor and that way allow the implementation to build up a profile. But after what I’ve been able to find out nobody has gone beyond that – which means that most of the personalization work done is done in the actual implementations of websites and not as a standardized feature in the content management systems. In a few cases the search engines used on the websites actually comes with more build-in personalization features than the CMS.

 

Mobile

Mostly due to the iPhone and increased 3G/HDSPA/edge coverage the web is no longer something that’s just meant for regular desktop/laptop computers. In fact in Asia, most internet usage is coming from mobile devices. So every CMS vendor is coming up with strategies on how they can deliver content across platforms. To be able to manage mobile content is a MUST these days – and the approaches vary from automatically transforming the html to supporting multiple rendering methods. A series of niche-players purely focusing on extending the mobile abilities of mainstream CMSs have already emerged.

 

Translation & multiple languages

As the world gets smaller and economies collapse in the english speaking world a lot of focus has turned to new, emerging markets in the east. This brings with it an increased focus on translation services and the CMSs ability to handle multiple languages. While European vendors have been used to the multi-language-challenges for years, it’s still a somewhat new challenge to US websites and systems. And once the system is in place, the actual translation begins. And in spite of what you might think it’s not just about changing the texts on a page. Multi language often means multi culture. Pictures, expressions, analogies and site structure often needs to be adapted. Some languages require right-to-left alignment. Illustrative pictures that are innocent in one culture can be highly offensive in another. A huge market for translation services and culture consultancy has emerged – and it seemed that no matter where you’d turn a Gilbane a friendly guy from a translation company would be there :-)

 

Connecting

I remember a day, not too long ago when I learned that a major danish company had an entire department of secretaries hired to take printouts from their ordering system and type them into their hour-management system, their CRM system and their invoicing system manually. None of the systems could interact in spite of them being based on the same platform – heck, even on the same servers.

Hopefully we’ll soon see the end of those days. There is a lot of focus on interoperability and connecting different systems – especially in the content management industry. Vendors are opening up their API’s, supplying web services and even building connectors to various systems. Most popular are connectors to enterprise search, sharepoint and crm systems like Salesforce and Microsoft CRM. Many implementations feature integrations to backend commerce-systems, product databases and invoicing systems – and we are starting to see a tendency to more standardized connectors as the systems mature.

EPiServer went down that road long ago, with Virtual path providers, Content Channels, open API, Microsoft CRM connector, Salesforce connector, EPiMore partner program and in version 5.2 we came out with PageProviders to connect live to any other datasource.

It’s easy to understand the popularity of this – ROI’s are easily measured in the number of work hours saved from being wasted on manually synchronizing data.

As a result of these efforts we are also seeing new protocols and standards emerge. Since it was proposed in august there has been a lot of buzz around CMIS (Content Management Interoperability Services) and many vendors are starting prototyping projects to be CMIS compliant when/if it officially becomes a standard. I talked to quite a few people about it and of course people are afraid that it will suffer from YASS (Yet Another Standard Syndrome) and die down – but still like the idea of a common way to integrate with other ECMs – or let other systems integrate with theirs. Together with a handful of others I’ve started the NCMIS project recently to see if we can scrape together a cross-vendor team interested in making a shared, open source .NET library/toolbox to help everybody adapt their systems to CMIS.

 

Collaboration on Content Creation 

Ok – I admit – to call this a trend just yet might be taking a step too far. But I predict that this is a trend we’ll see soon. When Google Wave launches for real I could imagine people getting used to constantly collaborate on construct contents. Today most CMS systems lack features that allows concurrent editors to actively work together on creating a piece of content – at most there’ll be a check-in / check-out functionality to avoid overriding each others changes. But wait and see!

 

Measurability

The last trend I’ll mention is probably one of the most important trends. Today it’s not longer enough for a feature on a website to be cool in a geeky sort of way. Today you need to proof that it’s cool. Most vendors today integrate with some sort of web statistics tool to show basic stats for the website – but we’ll see even more very soon. Many vendors are looking towards marketing engines, A/B testing, landing page optimization as built-in features that will allow website owners to test how well a given change to a website works on the visitors. Sometimes even simple changes in the text of a link can make the difference between success and failure for a website – and you’ll need to be able to measure it. Perhaps it’s the maturing market and technologies – perhaps it’s the collapse of economy, but measuring & tracking – often realtime – what’s going on on your website is definitely part of the current and future.

Wednesday, February 25, 2009

MaxSmash – Yet Another Babysmash application

My son, Maximilian (age 1½ years old), is (not unlike his father) a big fan of technology and computers. In fact, every time I open my laptop at home, he’ll notice, stop doing whatever it is he is doing and run to me, climb on my lap and start pounding the keyboard. While at the laptop, these are the things he prefers to do:

  1. Send messenger/skype messages to whomever I was talking to like this “lkhdsalnhjkdnnn vvvcccccccc……”
  2. Code in visual studio – unfortunately he hasn’t really grasped the entire “syntax” concept yet.
  3. Look at pictures of himself or other family members and yell out their name in an excited high pitch voice if he sees someone in the pictures he recognizes.
  4. Watch old russian cartoons on YouTube. At the moment his favorite is this:

To try to protect my computer, coding projects and messenger conversations I’ve been a big fan of Hanselmans Babysmash application that locks down the computer and lets a kid smash the keyboard all he wants – and see various figures, sounds and characters being displayed.

However, after a while Max started getting bored with it – so I’ve made my own that instead of characters and sounds simply display random pictures of people he knows. That’s a big hit at the moment.

All configuration (like setting up paths to image folders, cache-usage, etc) is done in an xml config file.

Once it’s running you have to hit ALT+F4 or CTRL+ALT+DEL to get out – everything else should be locked down.

Download it here

Comments are welcome!

Tuesday, February 24, 2009

Cool Tool: XDELTA

Yesterday, while trying to find a solution to a minor distribution problem I came across xdelta. It seems to be an awesome tool – just the way I like it: simple, fast, transparent and commandline based. It can find the difference between two binary files and store that compressed, and then later apply it as a patch. “Why is that neat?”, I hear you cry. Well – simple – now instead of storing a lot of really huge binary files where most of the contents is identical you can just store a source and then the different changes to that. Still don’t get it? Here’s the problem we’re going to solve with it.

Problem: X sales people located all around the world will get an external harddisk with a wmware image featuring all our amazing products for demo purposes. The problem arises whenever new versions of the image is created and needs to be distributed to all the sales people (probably going to happen several times a year). Not all internet connections are just as good for downloading 10gb files. Of course we could split it up, put it on an ftp-server or force everyone to install another of my favorite tools Free Download Manager. However, keeping our audience in mind, an automated solution would probably best.

Potential solution: On all the harddisks we put two images – a working copy they can use for demo’s and a virgin. Whenever we create a new version of the vmware image we’ll use xdelta to make a file containing all binary differences between the virgin image and the latest version – and at the same time compress the differences. We’ll do this using a command-line like this:

xdelta3.0u.x86-32.exe -e -5 -S djw -v -s "virgin-image-file" "newest-image-file" "difference-output-file"

The ‘-5’ indicates medium compression level, ‘-S djw’ is to turn on secondary compression, ‘-v’ is verbose mode – mostly because I’m a geek that likes to see what happens and ‘-s’ indicates the source file.
We can now let the sales people download the difference file together with a small batch-script that’ll apply the differences to their virgin-image and thereby recreating the latest version of the vmware image file using a syntax like this:

xdelta3.0u.x86-32.exe -d -s "virgin-image-file" "difference-file" "newest-image-file"

It tested it and it works. On a 9 GB image, I made some minor changes – like upgraded the EPiServer installed, removed old unused files, etc. That gave me a diff-file of 74 MB – which is a lot easier to download than 9 GB – and applying that file to a virgin image produced a new working image with the latest version installed :-)

Processing time on my laptop was around 800 seconds (< 15 min) for each action.

Enjoy

Sunday, January 4, 2009

Fun with card games

I just published one of my holiday pet projects on Codeplex. It's a very basic framework for building your own card games in .net.

With time, I'll also publish some sample projects, and hopefully even expand the project to include some basic AI logic as well.

Check it out: http://www.codeplex.com/CardGameLib

Even though it's still missing a lot of parts, I've already begun to use it for 2 other pet projects. One is a code competition I plan to put out soon - just looking for price-sponsors now, the other is a web-edition of the classic 500-Rummy card game, a game that I really enjoyed growing up - and still play when I'm vacationing with my family. Card games are an excellent form of entertainment - and remember, there's more than poker and blackjack to life.

Drop me a line - or leave a comment, if you want to contribute to the project, sponsor a price for the upcoming code-competition or just have an opinion to share :-)

WikiX - a Wiki for EPiServer CMS

Just before Christmas I was part of a team that launched WikiX an Open Source Wiki for EPiServer CMS 5 R2. Even though it's still in beta, it is actually really nice with a lot of cool features. WikiX is based on some of the thoughts and ideas presented here: http://allantech.blogspot.com/2008/10/wiki-vs-cms-difference-is-psychological.html.

wikix

See the announcement: http://labs.episerver.com/en/Blogs/Allan/Dates/112230/12/Announcement-WikiX-is-here/

Try it live here: http://wiki.demo.episerver.com/

Download it from Codeplex:http://www.codeplex.com/EPiServerWiki

Connect4 in Flash


Inspired by Giorgio Sardo who used my old Connect4 code to demonstrate moving a c# game to Silverlight for Mobile (when will you put that code online, Giorgio?) in a PDC 2008 session, I decided to use the same code as the basis of a project I had to do for a flash course last year.

This time, I didn't migrate all of the code, but rather made the flash talk to a back-end c# web service that calculated computer moves.

I know it's still a bit buggy - but some of you out there might enjoy it. While making it I found what could seem like a bug in ActionScript 3 - making it quite difficult to drag and drop nested objects....But I might share more about that later.


Try the original plain html here.

Try the new flash version here.

Code and written project will be available later.

Friday, October 24, 2008

PDC 2008 - Here I Come

Travel time again. Destination Los Angeles. There I'll spend the next week learning everything that Microsoft will try to teach me - and probably then some.
See you all at the parties! I'll be the guy in a gray t-shirt, with a laptop and a high-tech phone. If you find me, I'll buy you a beer or something!

Wednesday, October 22, 2008

Flash Rss Reader

Another little flash gadget I just made... An RSS reader. Yes, I know it's an original idea - but it seemed like a good, comprehensible, and to some degree useful thing.

For fun I made iPhone style navigation - in the sense that you need to drag right or left to move between items.
It lists the blog feed from labs.episerver.com.

The trickiest thing was to handle all the security around loading a URL in flash. Flash can only load data from the same domain as it is located on (or another domain that has a crossdomain.xml file in the root, allowing flash access). Anyway, the simple solution was to make a small rss proxy in c# (around 3 lines of code) and put it on my test-domain together with the flash app.





Allan version 1952

Just stumpled upon Yearbookyourself.com. What a cool feature! You can see how you would look like on a high-school yearbook picture from 1950-2000.

In case you're wondering, here's how I would have looked in 1952 (when I was -27 years old).

Allan1952

Monday, October 20, 2008

Oh, the power of DHTML

I spend Sunday visiting Copenhagen's Zoological museum with my wife and son. Great museum, even my 14 months old son loved it - all the stuffed animals to look at and pet! Nevertheless, I came across some stuffed lemmings there and quickly found myself floating back memory lane to that wonderfully 90-something game that I used to spend so many hours enjoying.

I figured someone probably had put it online by now - but I hadn't imagine a DHTML+Javascript only version of it. Check it out! Very cool.