Friday, August 08, 2008

A couple of days ago I discovered a bug in Hotmail that you can read about here.  As it turns out it was both a bug in Hotmail and in my code (sort of), and a type error in my blog post causing some confusion. Thanks to Rune Grothaug for getting me in touch with the Hotmail team.

The bug in Hotmail is related to how they query for content id's in the email. It's too expensive to load the email into a html parser to get the id's, so they do a string match instead. Here's how I understand it:  When they try to match nnug10 they actually get nnug1 back (as the first match). One solution suggested by them was to reverse the order of the searches allowing nnug10 to be found first. I'm not sure if this is what they're going to do. (Update: I got confirmation that this is the solution they're going for)

As for my bug it was that I forgot to add the file extension to the ContentType.Name (see code below). This is the name that actually gets displayed for the attachment image in the mail. In Hotmail (and Gmail for that matter) it shows all linked resources as attachments, and the name of these attachments had no extensions (e.g. jpg). A workaround for the Hotmail bug could have been to do the same with the ContentId. When the id is nnug10.jpg it actually works! In my blog post I said that the cid's where nnug0.jpg, nnug1.jpg etc. which was not the case. It did not have the .jpg extensions.

Taking the above into account this makes the Hotmail bug far less serious than I originally thought.

But..., when you see the property ContentId you're thinking it can be whatever only it's unique right? This is why I didn't think much of what the ContentId was as long as it was unique. However, to be absolutely sure that something like this will not happen again I changed the cid's to be guid's instead (this was also suggested by the Hotmail team). Better safe than sorry :-)

Here's the code after my modifications:

LinkedResource img = new LinkedResource(stream, mediaType);
img.ContentId = guid;
img.ContentType.MediaType = mediaType;
img.TransferEncoding = TransferEncoding.Base64;
img.ContentType.Name = img.ContentId + fileExtension;
img.ContentLink = new Uri("cid:" + img.ContentId);
resources.Add(img);
Friday, August 08, 2008 8:30:42 PM (W. Europe Standard Time, UTC+01:00)
 Thursday, August 07, 2008

Update: More on this story here.

I've been playing around with an email tool that I've created to send out emails to NNUG members. It's just a simple command line tool sending an email to each person in a list to avoid using bcc which sometimes get hooked in a spam filter. Another thing this tool does is to take an html page (an html formatted email), scan it for images and embed the images using the AlternateView class and its LinkedResources collection for sending as an html email.

The emails sent by this tool looked ok in Outlook, Gmail and Hotmail on every test I did. Except for when I decided to use the tool to send out an official NNUG invitation to 300 members! The only change I had done was adding one extra image. I noticed that the email I got on my Hotmail account had a wrong image at the end. The image used was the same as the second image in the email. The reason was not hard to find.

When I add images to the LinkedResources collection, I name the images/files nnug[someNumber].jpg like this:

nnug0.jpg, nnug1.jpg, nnug2.jpg etc.

This worked fine for all images up to nnug10.jpg. Can you see why nnug10.jpg did not work and what the bug is? The last image that was supposed to be nnug10 was showing up as the second image instead (nnug1). E.g. nnug10 = nnug1! Hmmm.... Come on!

Then my apology. To all members of NNUG with a registered Hotmail account and to Christian Weyer:

I'm sorry that I did not discover this bug before, so I could have changed my algorithm. Sorry to you Christian for being nnug1.jpg! You replaced the NNUG logo, resulting in the email ending with:

  Kind regards [image of Christian]

instead of

  Kind regards (image of NNUG logo)

...giving the email a bit different meaning than I intended :-)

Btw. don't forget to sign up for the NNUG events by Christian Weyer and Dan North 25th and 27th August!

.Net | Fun | Microsoft | NNUG
Thursday, August 07, 2008 12:43:23 AM (W. Europe Standard Time, UTC+01:00)
 Tuesday, May 27, 2008

Brian Harry over at the TFS team has a great post about the new features that will be available in the coming SP1 for TFS 2008.

Tuesday, May 27, 2008 6:47:50 AM (W. Europe Standard Time, UTC+01:00)
 Saturday, May 24, 2008

Pex Earlier this month Fredrik Normén wrote a post about argument validation. Yesterday Rune Grothaug from MS Norway posted a link to a new tool MS has developed in their research lab called Pex (Program EXploration). Combining these two (argument validation and Pex) have to be a perfect match.

.Net | Testing | Tools
Saturday, May 24, 2008 10:31:09 PM (W. Europe Standard Time, UTC+01:00)
 Tuesday, May 13, 2008

Update: This article is not limited to deploying applications to Vista, but also when changing files that are only writeable by administrators (e.g. files in the Program Files directory).

If you have not made specific changes to your installation to support UAC in Vista, this is for you. I hope this will help others to not spend many days of confusion, desperation and sleepless nights like I have.

Lately I've been getting reports from some of my coworkers running Windows Vista that the app.config file in our application was not updated after installation. I've also experienced this myself. We've solved them without knowing exactly how (which I hate). Typically "I uninstalled the application and installed to a different location, and it worked!" Well, this is a workaround that are not particulary popular to any of our customers, so I dived into the problem to find the exact reason.

To save you some reading I'll just say that the reason and solution is to provide your application with a manifest file to handle UAC in Vista as described in this article: Create and Embed an Application Manifest (UAC) I haven't actually tried this out yet, but I trust the article to be correct :-)

Virtualization
But that's not the interesting part. The interesting part is what happens (or what can happen) if you don't have an application manifest for this purpose? If your superstitious you might think that something weird is going on with your computer. If you're like me you KNOW that something weird is going on with your computer, and you need to find it and fix it. The weird thing is Vista virtualization.

"File virtualization addresses the situation where an application relies on the ability to store a file, such as a configuration file, in a system location typically writeable only by administrators"

"Virtualization is implemented to improve application compatibility problems for applications running as a standard user on Windows Vista."

As I write this I have exactly this problem on my computer. I've installed our application (Contiki ECM) to this location: C:\Program Files\CMA Contiki AS\Contiki ECM\. This is where I've always install our app. So today I installed and checked that the app.config was updated with all my changes done during installation. And it hadn't. Actually it was updated, but not with my changes. It looked like an old file that I had some time ago. How could this happen?

Textpad .vs. Notepad
To make this even more confusing, I discovered this reading the file in TextPad, but when opening the file in Notepad it was fine. All my changes was there! So I thought that this was a TextPad problem. I started our application, but it turns out that when .Net tries to read the config file, it reads the same old stuff as TextPad did, resulting in old config to be loaded into our app. Why does Notepad get the right file? I don't know. Please tell me if you do.

The solution
So after Googling for a while I found this article on MSDN, and things started to make sense. But first let me show you what it looks like on my computer. The file causing my headaches are Contiki.Windows.Application.exe.config.

VistaUNCImg1 
Do you see when it's modified? 08:56 this morning, but the file that is being opened is from 13th of April! How do I know? Well, if you have a look at the virtualized files which you'll find in C:\Users\Username\AppData\Local\VirtualStore\[Your path], it might help out. So I looked at C:\Users\1jontor\AppData\Local\VirtualStore\Program Files\CMA Contiki AS\Contiki ECM and found this:

VistaUNCImg2 
Modified back in April. I opened this file and it was exactly what I saw in TextPad. But this file is the same both in TextPad and Notepad! :-)

Explorer gives you a shortcut to the Virtual Store folder if any files are virtualized, and will show this button in Explorer:

VistaUNCImg3

The end
A couple of notes from the MSDN article:

"When you enumerate resources in folders and in the registry, Windows Vista will merge global file/folder and registry keys into a single list. In this merged view, the global (protected) resource is listed along with the virtualized resource."

"The virtual copy will always be present to the application first.... even if [some file] is updated"

Even if the file is updated!? Who though of that? Was that really such a good idea? I can see what they where thinking, but it would have saved me a lot of work getting an error message saying "Access denied"...

To end this off I picked another good quote from the article:

"Microsoft intends to remove virtualization from future versions of the Windows operating system as more applications are migrated to Windows Vista."

I appreciate that... :-)

Tuesday, May 13, 2008 9:08:42 PM (W. Europe Standard Time, UTC+01:00)
 Friday, April 11, 2008

The first .Net user group ever (as far as I could find out) was started by Ruth Walther in Seattle December 2000. It seams like this group is no longer active and I was unable to find out why. Anyway, today you'll find a user group in almost every major city in any country. And if you don't have a user group where you live, I think it's about time you start one! :-) Seriously, it's not that hard and you'll be a hero where you live! :-)  I can really recommend the experience and people will defiantly appreciate someone taking the first step to get your city on the user group map.

NNUG2After the first user group started up in the US many others soon followed during 2001. To pick a few other countries I'm familiar with I can say that my home country Norway started their first user group in Oslo October 2001 and in my city Bergen we started up in December 2002, the London .Net User Group was started in 2002 and Sydney Australia in April 2002, .

It's free
HangingDollars Most user groups I know of don't charge for membership. Many don't even have memberships, but use the word of the people to announce their meeting or that "everybody" knows that their having a meeting last Wednesday in every month, and it's just to show up. User groups rely on local, national and/or international sponsorship. If your country have a Microsoft company present, they usually help out. This can be to help you get in touch with speakers, sponsor travel costs (for speakers), pizza and the like. The user group I run in Bergen use local sponsors for pizza, but get some help from Microsoft for travel costs. When requesting speakers it's often smart to provide them with consulting when they visit your city. This is a nice way of helping your local companies get excellent consulting and it make the speakers trip to your city a bit more attractive.

Why are user groups so popular?
There are many reasons for this and they vary from user group to user group. But from my experience there are some general things that should more or less apply to all user groups:

  • It's free
  • You get free food (usually pizza)
  • You get to meet other people from other companies to share experience with, that you would usually not meet outside the user group
  • You learn a lot
  • Keeps you up to date on what's going on
  • Communities in general are popular

INETA
Ineta INETA is the mother organization for all .Net user groups. Its an acronym short for International .NET Association. You will find user group related to SQL server, VB, SharePoint and other .Net related products. They all have in common that they focus on some type of Microsoft .Net related technology. INETA is divided into five geographical areas; North America, Latin America, Middle East and Africa, Asia Pacific and Europe. My experience is with INETA Europe, but I expect it to work much the same in the rest of the world. INETA Europe have among other things a Speaker Bureau with lots of good speakers. As a member your user group can request two speakers per year. These are top notch speakers! In Europe you'll see names like Ingo Rammer, Christian Weyer, Dino Esposito to mention a few. As a member your user group will also get a quarterly kit where you can select some books, cd's and other stuff to use as giveaways for you members, prizes etc. INETA also helps getting user groups started, especially if it's the first user group in the country. If there are existing groups in the country, the other groups usually helps you getting started in your city. That's how communities work!

.Net | Microsoft | NNUG
Friday, April 11, 2008 3:03:52 PM (W. Europe Standard Time, UTC+01:00)
 Thursday, March 13, 2008

MouseClickServer deployment of ClickOnce? Isn't ClickOnce client deployment? Yes, it is. However, you will have to deploy the ClickOnce files to a server, right? I feel this is a poorly documented step and I thought I share some of my experience around this.

So what's the problem? The main issue is the deployment manifest file. If you've worked with ClickOnce you know about this file, if not here's a (very) short description. The deployment manifest includes information about where the ClickOnce application is located (e.g. http://myServer/myWD/myApp.application) as showed in the following snippet:

...
<
deployment install="true" mapFileExtensions="true" trustURLParameters="true"> <subscription> <update> <beforeApplicationStartup /> </update> </subscription> <deploymentProvider codebase="http://myServer/myWD/myApp.application" /> </deployment>
...

This file needs to be signed with a certificate to be valid, which means that any changes to this file makes it invalid and you'll have to resign it. This is a good thing for security, but it causes some problems regarding deployment. The url specified in this file must be changed when deployed at a server. Unless you want to get all information needed from your customer and create the deployment package before sending it to them or force them to set up a server named myServer ;-). I don't think that solution is very likely to be used in production systems. So what you need to do, is make the installation (e.g. msi) change the manifest file and resign it during installation.

Microsoft has provided us with a tool to do exactly this. However, you're not allowed to redistribute it. Another issue is that you need to have a certificate for signing and you don't want to have your corporate certificate laying around in your msi. The most common solution around this problem is to prompt the user during installation for a certificate (like suggested here). But then your app is signed by someone else's certificate, which is probably not what you want.

I will now suggest a different solution to this problem. In the System.Build.Tasks.dll you'll find much of the functionality needed to do the same thing as Microsoft's Mage.exe is doing. The nice thing about this dll is that it's a part of the default .Net Framework installation. Here's a short description of the classes needed:

DeployManifest
An object model for the manifest file. Gives you direct access to specific parts of the manifest and makes it really easy to make changes.

ManifestReader
Have a static method (ReadManifest) which let you read and return the manifest you are going to work with.

ManifestWriter
Use the static method WriteManifest to write your changes back to the manifest file.

X509Certificate2
Your certificate to sign the manifest file with.

SecurityUtiities
Has the static method called SignFile which let you sign your manifest.

By using the classes described above it should be quite easy to achieve the same as with the Microsoft utility. Here's an example:

using System;
using System.IO;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Build.Tasks.Deployment.ManifestUtilities;
...
string
manifestPath = @"C:\Temp\myApp.application"; string deploymentUrl = "http://myServer/myWD/myApp.application"; DeployManifest manifest = (DeployManifest)ManifestReader.ReadManifest("DeployManifest", manifestPath, false); manifest.DeploymentUrl = deploymentUrl; ManifestWriter.WriteManifest(manifest); X509Certificate2 certificate = new X509Certificate2(GetCertificateFile(), "password"); SecurityUtilities.SignFile(certificate, null, manifestPath);

There is one important step we need to solve. How do we protect the certificate we need to sign the manifest file. For this I suggest you incorporate this into your tool (either a command line tool or a .Net library) by using Build Action = Embedded Resource. This will make your certificate inaccessible for most people. If you want to secure it even more, you can crypt it in however way you want. I leave this up to you ;-) In my code above I've done this in the GetcertificateFile() method:

X509Certificate2 certificate = new X509Certificate2(GetCertificateFile(), "password");

There is of course one other issue which you'll have to consider. What if someone uses your custom tool to sign their ClickOnce app? So you need to protect this as well with a password or some other mechanism. If you have a good suggestion to this, please let me know.

Thursday, March 13, 2008 3:03:15 PM (W. Europe Standard Time, UTC+01:00)
 Tuesday, February 26, 2008

You might argue both, but that's beyond the point :-) I've been thinking lately about how different programmers get their work done. If you look over the shoulders to 3 programmers, none of them is working the same way. The first difference I tend to notice is the use of keyboard shortcuts. Personally I've always been a fan of shortcuts, especially in development environments like Visual Studio, but also general shortcuts in Windows or other applications. For instance I never do File -> Open. I always use ctrl -> O and it always annoys me when a program does not support the most common shortcuts. However, I still feel I can learn and use more of them.

We can divide developers into three groups related to the above:

  1. Love the mouse and rarely use shortcuts
  2. Use mouse often, but use shortcuts for the most common actions
  3. Use the mouse only when there's no shortcut for the action.

I think I can put myself in category 2 and I'm not sure if I want to or are able to be in category 3. One important aspect to consider before I dig myself to deep into this, is that you don't necessarily produce better software by using a lots of shortcuts (obviously). However I'm quite sure that a developer in group 3 produce code faster than a group 1 developer. But one can argue (if you're a bit extreme) that the quality of the code produced by group 1 is better, because they get more time to think :-) But seriously you can't use this type of groupings for defining developers, but in general I think many developers could benefit from using more shortcuts.

Here are the most common shortcuts in Visual Studio 2005 as I see it:

Builds    
Ctrl+B, Ctrl+S Build BuildSelection
Ctrl+Shift+B Build BuildSolution
Ctrl+Break Build Cancel
     
Debugging    
F5 Debug Start
Ctrl+F5 Debug StartWithoutDebugging
Shift+F5 Debug StopDebugging
F10 Debug StepOver
F11 Debug StepInto
Ctrl+F10 Debug RunToCursor
Shift+F11 Debug StepOut
Ctrl+Shift+F10 Debug SetNextStatement
F9 Debug ToggleBreakpoint
Ctrl+Shift+F9 Debug DeleteAllBreakpoints
     
Navigation    
F12 Edit GoToDefinition
Ctrl+F12 Edit GoToDeclaration
     
Other    
Shift+Alt+Enter View FullScreen
Ctrl+Shift+F12 View NextError
Ctrl+Alt+P Tools AttachtoProcess
Shift+Alt+A Project AddExistingItem
Ctrl+K, Ctrl+M Edit GenerateMethodStub

You probably know where and how already, but if you go to Tools -> Options -> Keyboard in Visual Studio you can define your own shortcuts. This is a great feature of Visual Studio that let you create custom shortcuts for almost every action you can do with a mouse. You can either change an existing shortcut or define new ones. Here's a screenshot of the shortcut dialog in VS:

image

Commands are displayed alphabetically after some type of menu structure (e.g. Edit.Copy), though there a many more commands than you can find in the menu. This list is of course populated dynamically which means you'll find commands for 3rd party VS plugins like e.g. ReSharper. One thing to be aware of though is existing shortcuts. If you for instance want to have the shortcut Ctrl+V, Ctrl+A, you will override the Ctrl+V command for Paste, which is probably not what you want.

Tuesday, February 26, 2008 2:53:51 AM (W. Europe Standard Time, UTC+01:00)
 Tuesday, February 12, 2008

NNUG_JavaBin The 27th of February Anders Norås will come and have two presentations on Domain Specific Languages (DSL). First we only planned one, but when I asked Anders if the presentation would be strictly .Net he suggested having two presentations, one on .Net and one on Java :) I thought this was a great opportunity to get the two local communities in Bergen together under the same roof. Sometimes there is sessions that is not directly connected to a technology platform and these types of presentations are great for joining forces and share experiences. Hopefully NNUG will visit JavaBin next time something like this comes around.

I will post more info about the sessions later and if you're a member of NNUG you will get the meeting invitation shortly. The same goes for JavaBin members.

Really looking forward to this and I hope to see you there.

.Net | Events | Java | NNUG
Tuesday, February 12, 2008 10:39:29 AM (W. Europe Standard Time, UTC+01:00)
 Friday, February 08, 2008

Update: I've found a temporary solution. After inspecting which files was in our package I found a 3rd party component that we don't use anymore but still had a reference to. This was references by our business layer, which all our web services use, hence this dll was in every bin folder on every web service. Since the size of the file was quite big it was enough to get the installation down to a reasonable size and avoiding the described error message.

For a while now our msi file that contains the application server for our product has not been working. Not an msi that our customers have, but one we're about to ship in two weeks. I've had my hands full for a long time, but today I finally got around to check what was causing the problem. Here's a screen shot of the error I get:

MsiInstallError

After a quick Google search I found that this is related to a bug on Windows Server 2003 and Windows XP. Cause:

This problem occurs if the Windows Installer process has insufficient contiguous virtual memory to verify that the .msi package or the .msp package is correctly signed. 

Fantastic! I will not go and ask all our customers to install the hotfix on their servers. That's just to stupid. About now you're probably thinking something like "How big is their app-server really?" or "What product can get to big for an msi file?". I can tell you... The size of the msi is 576MB. No images, no database, just pure .Net dll's! And actually we're not alone. Visual Studio Service Pack 1 had the exact same problem! Go figure. And even better, there is no hotfix for this on Windows XP.

Have we been coding like mad men for a decade and producing tons of code? I wish (or maybe not) :) The answer is simpler than you might think. Our application server contains web services only. At the beginning of our project we took an architectural decision to have our web services separated in virtual directories (or projects in VS). This to be able to update parts of our application without affecting the whole system. This was part of a master plan around the smart client principle and would let us deploy small modules into our application which dynamically loads the new behavior. As it turns out we have almost never done this in production. The drawback of this is of course that you get many of the same dll's scattered around in many virtual directories. And when you have many web services (by web services I mean asmx files and not web methods, 43 to be exact), and each one is dependent on your business and data access layer (which is quite huge) and more, megabytes is piling up.

So what's the solution? Well, since we don't really use this as intended we can just merge our web services into one and we will be home free. Except you don't do that two weeks before deployment with acceptance testing coming up. So I have to think of something else. The only solution I can see now is to find some way of making the msi smaller, which at the current time I don't have the faintest idea of how to accomplish. I can use a setup launcher (exe) which will probably solve it, but that will not make our customers very happy. Hopefully I'll figure something out during the weekend, or maybe you have a solution?

Friday, February 08, 2008 10:37:08 PM (W. Europe Standard Time, UTC+01:00)
 Saturday, February 02, 2008
Mark 17th and 18th of July June (Programutvikling's event site mention both June and July, but June is the correct month) in your calendar. Microsoft Norway and Programutvikling has managed to attract some great names. Check this out: Scott Hanselman, Roy Osherove, David Chappell, Mats Torgersen, Rafael Lukawiecki and Mary Poppendieck! Is that a great line-up or what? I wonder if they got this idea from my Developer Conference in Bergen post? ;)

For now there's not much information out there, but you'll definitely hear more the coming months. Rune Grothaug's blog from the Microsoft DPE team is a great source for events in Norway. Programutvikling has the event on their site here.
Saturday, February 02, 2008 12:22:49 AM (W. Europe Standard Time, UTC+01:00)
 Thursday, January 31, 2008
NNUGPizza at NNUGIn my previous post about Developer conference in Bergen I said some not so nice things about the .Net community in Bergen (also called criticism). After today's meeting I take it all back. Everybody that showed up today proved me wrong. On previous meetings we were satisfied if 20 people showed up. Actually 20 people is/was our goal for average attendance for 2008. So what happened today? 43 people showed up to see Erik Leivestad and Thomas Eyde talk about Agile Project Management and Test Driven Development! For a time there I was worried that we didn't have seats for everybody. I really hope that this is the new norm at NNUG Bergen and not just a onetime incident.

Erik LeivestadWe also did a quick survey before we started the meeting. We asked how many project managers and how many developers was in the audience. To my surprise almost everybody was developers. I was thinking that because of the Agile PM talk we might have attracted a different type of crowd than we usually do, but that was not the case.

Thomas EydeThe second question was how many was here for the first time. About 50% of the crowd raised their hand. This was not a surprise for me since I checked the statistics the day before, but it's nice to get it confirmed :)

The last question was how many will come to the next meeting, and that was depressing. The response was 3-4 hands at best. I guess you where thinking: "let’s have this meeting first and see how it goes" :)

A big thank you to everybody that showed up today and a special thanks to Erik and Thomas for spending their spare time to educate us about agile processes and tools. It's really awarding to see a big crowd showing up when you've spent a lot of time (without getting paid) getting speakers and subjects that you hope people will like and find interesting. Finally I hope to see you on our next meeting the 27th of February. Until then, happy coding!

.Net | Agile | Events | NNUG | Scrum
Thursday, January 31, 2008 12:38:13 AM (W. Europe Standard Time, UTC+01:00)
 Friday, December 21, 2007

During my involvement in NNUG I've been playing with the thought of having a developer conference in Bergen. Funny enough I first started to consider this when we had some problems getting people to come to our NNUG events. I couldn't figure out why Bergen had such a low participation when other (smaller) cities in Norway managed quite good. I've also got reports from Microsoft saying that MSDN Live didn't do to well in Bergen either. Is this just how it is in Bergen? We just don't want to get our hands on new knowledge? Or is there so much info on the web that we don't see the need for meeting up in person? Maybe Bergen is just the worst city in Norway to be a developer? We just go to work to get our paycheck and don't really want to be bothered with updating our knowledge unless forced to? I don't think so and sure don't hope so! My impression is that the Java community in Bergen does not have the same challenges.

We will of course always have Mort though (see Jeff's articles here and here). Maybe Bergen is just overloaded with Morts? ;) However, I think a dev conference in Bergen has something to offer him as well.

So why do I want a dev conference in a city where developers don't participate in their local .Net community? First of all it's because I don't think the above is true. I think there is a lot of great developers and companies in Bergen working with development that would both see the benefit and be proud to host a dev conf in their city. Second, I think NNUG will benefit greatly from this and raise the visibility around the .Net community in the city. Thirdly, I have too much free time on my hand so I'm looking for something to do in my spare time (kidding).

So what do you think my dear reader? Is there room for a dev conference in Bergen? Would you come? And even better, would you volunteer to make this a reality? I'm volunteering now, but I need some helpers... :)

You might state that we already have a developer conference in Bergen and you would be right. It's called Roots, but I'm thinking about a different kind of conference. Roots is an international niche conference around OO (Recent Object Oriented Trends), but I want a general Norwegian (Nordic) dev conf. Even though I'm a .Net guy and would like .Net tracks, I also think there is room for Java and agile tracks.

And to all of you who have been going to NNUG regularly I apologize. The criticism in this post is to everyone except you ;)

.Net | Events | NNUG
Friday, December 21, 2007 12:47:35 PM (W. Europe Standard Time, UTC+01:00)
 Monday, November 05, 2007
VSOrcas.gifThe wait is almost over. At TechEd Barcelona Microsoft announced the release date of Visual Studio 2008 and .Net Framework 3.5. Check out the official press release here: http://www.microsoft.com/presspass/press/2007/nov07/11-05TechEdDevelopersPR.mspx

.Net | Events | TechEd | Tools | VisualStudio
Monday, November 05, 2007 11:36:07 PM (W. Europe Standard Time, UTC+01:00)
 Sunday, August 19, 2007
If you are like me you probably have a hard time finding something to create when trying out new stuff.  This time I sat down and tried to figure out something to use LINQ and Silverlight for and maybe WCF, WPF and Ajax as well. At the time I was watching TV and the EPG (Electronic Programming Guide) didn’t work, so I started to look for a web site with a program guide supporting reminders and other nice features to let you know what’s on TV. I didn’t find anything good.
I then started to look for an xml/text format for TV programs. I did some searching and came across xmltv. Nice! I now had an xml source looking something like this:

<tv>
  <channel id="channel1">    
    <
display-name lang="nb">Channel 1</display-name>
  </channel>
  <channel id="channel2">
    <display-name lang="en">Channel 2</display-name>
  </channel>
  ...
  <programme start="20070801033000 +0200" stop="20070801053000 +0200" channel="channel1">
    <title lang="nb">Program 1</title>
    <desc lang="nb">Program description.</desc>
    <credits>
      <director>...</director>
      <actor>...</actor>
      <actor>...</actor>
    </credits>
    <date>2004</date>
    <category lang="en">movie</category>
    <category lang="en">drama</category>
  </programme>
  ...
</tv>

So now I had an xml document containing all the data I needed and this was a perfect time to try out XLINQ. I decided to stick with the LINQ query syntax and not mix in Lambda expressions to keep things simple and readable. I came up with this expression to get all TV channels:
public List<TvChannel> GetTvChannelsWithoutGuide()
{
IEnumerable<TvChannel> channels; try
{ XElement tvGuide = XElement.Load(_xmlFileLoc);

channels = from c in tvGuide.Descendants("channel")
orderby (string)c.Element("display-name") ascending
select new TvChannel
{
Id = (string)c.Attribute("id"),
Name = (string)c.Element("display-name"),
Lang = (string)c.Element("display-name").Attribute("lang"),
TvGuideLoaded = false
};
} catch (FileNotFoundException fileNotFoundEx) { throw new FileNotFoundException(string.Format("Xml file for tv guide not found at {0}",
_xmlFileLoc), fileNotFoundEx); } return channels.ToList<TvChannel>(); }

The XElement gives me the complete xml document that I can use XLINQ expressions on. In my query I’m looking only for TV channels, so I specify that in the query by

    from c in tvGuide.Descendants("channel")

This gives my a variable c that I use in my orderby clause and select statement. The orderby clause

    orderby (string)c.Element("display-name") ascending


uses the c variable to access the “display-name” element to set order by. But it’s the select statement which is the cool thing here! First here a listing of the TvChannel class:
[Serializable]
public class TvChannel {
public string Id { get; set; } public string Name { get; set; } public string Lang { get; set; }

[XmlIgnore]
public IEnumerable<TvProgramme> TvGuideNonSerializable { get { return TvGuide; } set { TvGuide = value.ToList(); } }

public List<TvProgramme> TvGuide
{ get; set; } public bool TvGuideLoaded { get; set; } } 
Ignore the TvGuideNonSerializable property for now. By using select new TvChannel I can create an object of my TvChannel class an assign data from the xml document to my properties. I just love this syntax! It’s really nice and easally understandable. Another cool feature (running VS 2008 Beta 2) is that you get ItelliSense in LINQ for your classes, like this:

LinqIntellisence.png

I also created other methods for retrieving all programs for one channel, all channels etc. At the time of writing I’m working on a Silverlight implementation for the TvGuide which I hopefully can show you soon. And later I’ll make all source code available.

.Net | CSharp | Linq | TvGuide | VisualStudio
Sunday, August 19, 2007 12:11:51 PM (W. Europe Standard Time, UTC+01:00)
 Tuesday, August 14, 2007
TheDotNetShow.jpgJust saw that there was a new episode (Silverlight) of The .Net Show out, and it started with telling us that this is the last episode! I've been watching this show on and off since its startup in December 1999! The show has been running for almost 8 years which makes this the longest running series at Microsoft. However, all good things have to come to an end. But it’s sad. I’ve really enjoyed this show and for a time (before blogging and rss) it was one of my few sources to new .Net technology inside the walls of Microsoft. Robert Hess’s (the host) last words in the show were:
Well, until next time, we'll see you on the Web and I might recommend you check out channel9.msdn.com. You never know who you might see show up there.
So I guess this isn’t the last time we see Robert. Thanks for all your hard work on this show during the years, giving us the latest news and insight into .Net technology! Salute!

Tuesday, August 14, 2007 9:55:54 AM (W. Europe Standard Time, UTC+01:00)
 Saturday, August 11, 2007