 |
|
 |
 |
Wednesday, February 28, 2007 |
 |
Tuesday, February 20, 2007 |
 |
Thursday, January 25, 2007 |
 |
Wednesday, January 03, 2007 |
I have been re-awarded MVP for Visual Developer ASP/ASP.NET.
 |
Monday, October 30, 2006 |
Last Tuesday, I held the talk "Advanced Code Access Security" at UG Styria in Graz. This talk was originally part of the MSDN Security Briefings held in Austria earlier this year, for which MS Austria had asked MVPs to help create and deliver security content. Advanced CAS seemed an interesting enough developer topic to re-run at user groups, and Mario (the author of this session) has allowed me to publish the slide deck and demos for the general public.
AdvancedCodeAccessSecurity.pdf (4542 KB)
AdvancedCAS.zip (599.6 KB)
Please note that I have published only demos four (setting CAS via setup) and six (using CAS in addin application) - those are the "completed" versions of the demos.
 |
Wednesday, April 12, 2006 |
During the MVP Open Day in Munich last week (Friday & Saturday), we had a presentation by Talhah Mir (ACE Team, Threat Modeling blogs) on threat modeling - which (I hope) everyone is familiar by now. During the talk, he pointed us to an interesting resource: A Chronology of Data Breaches from the Privacy Rights Clearinghouse. Quite an interesting list of incidents, which gives you an idea of the ratio of actual hacking vs dishonest insider, as well as other types of security breaches.
 |
Monday, January 09, 2006 |
Today, I got my MVP award package, which kind of makes it fully official. No surprise with my area of expertise: Visual Developer ASP / ASP.NET.
 |
Wednesday, January 04, 2006 |
Only a little more than two weeks to go until our yearly Community Wintercamp - "our" as in German .NET mailing list community. The agenda [German] has been posted quite some time ago, and this year it's going to be great because we already have tons of snow (literally). If you are a .NET aficionado living nearby (I like to define "nearby" as Switzerland, Germany or Austria) you are welcome to join a band of geeks in the snow! To whet your appetite, take a look at the photos and accounts of the past events.
 |
Monday, December 05, 2005 |
Today, a member of our German .NET community asked if it is possible to programmatically query the Google page rank. He had seen it done in PHP (here on the Google Community site), but didn't have time / PHP skills to translate it. All I found on a rather shallow search was PullRank, which I'd describe as non-fit for server use.
So I decided to set out to convert the PHP sample. Being PHP-challenged myself, I decided to give the PHP to ASP.NET Migration Assistant a shot. Whoha! That converted code is the most convoluted contraption to be called code I have seen - ever. I tried to get it to run, but failed because the conversion left me with some loose ends.
Instead of giving in, I contacted Christian Wenz to lend me a hand because he has some PHP experience. He thankfully hosted an "annotated" version of the PHP script so I could look at the output of various stages to test my solution with known-good values. That was most helpful.
Instead of doing a Web site demo application with everything intertwined, I split up the project into two - GPRDotNet being a DLL assembly project you can reference in any type of .NET application (Windows Forms, Web Forms, you name it), as well as a simple Web frontend to demo the usage: DemoSite.

Querying the page rank is really simple - the following snippet is the code from the "Check PageRank" button event handler:
protected void doCheckPageRank_Click(object sender, EventArgs e) { GooglePageRank pr = new GooglePageRank();
string url = webSiteUrl.Text;
try { string rank = pr.GetRank(url); thePageRank.Text = rank; } catch (Exception ex) { // this is rather chatty (telling the end user everything *IS* a bad idea) thePageRank.Text = "Requesting the page rank failed. Reason: " + ex.ToString(); } }
I want to emphasize that the code for the GooglePageRank class is a rather quick & dirty port of the PHP code and that it does not contain the necessary error handling you would expect for a server-side library. After all, it is just a proof of concept for our community.
Finally, here is the source code: PageRank.zip (26.89 KB)
If you find errors, please leave a blog comment so others know about improvements. Thanks!
 |
Saturday, October 15, 2005 |
 |
Monday, October 03, 2005 |
Rob Howard blogs about this acquisition. Cool things coming to Community Server!
At the MVP Summit, the EMEA / LATAM ASP.NET MVPs were partnering to prepare feedback for the team (any more information and I have to shoot you, or shoot your lawyer if you prefer). We were having a jolly good time (we all agreed to spend money on beer and... but that's another story). At that point I suggested that we (book authors, bloggers, article authors, et al) should slap a mandatory warning on our sample code / application: "Not built to scale."
However, in the German community we have an application built to scale: CodeFairway.NET. I wrote an overview article, now Alex followed up with an in-depth look at the features, architecture and techniques of CFW. Read Code Behind: CodeFairway.NET.
 |
Sunday, October 02, 2005 |
The MVP Summit 2005 is over, and with the exception of Transportationgate, it was a great event - even though I had attended PDC05, and worked with Whidbey for years now. I don't primarily come for the news, but talking to other MVPs as well as product group members.
On the community side of things, Alex and I put the finishing touches on the localization feature of CodeFairway.NET, which now includes the ability to play a tournament in a specific timezone.
You don't know what CodeFairway.NET means? Let me introduce .NET Golf to you:

Now, that is intentionally a graphic, to show that sites made by programmers for programmers need not be ugly but can be quite appealing. Here goes the text for easier reading:
"What is .NET Golf?" How did the union of a programming technology and a lawn sport come about? Well, the idea is simple and fascinating: in 'classical golf' the winner is the player using the least number of strokes to hole out. We transferred this concept to programming: whoever needs the fewest number of characters to solve a given programming problem wins the tournament. Speed and elegance of the solution are not criteria.
Each tournament extends over a given time span, after the end of the tournament we hold 'post mortems', i.e. the participants explain their solutions (so that there may be a great wailing and gnashing of teeth behooving the creative abuse of the technology).
.NET Golf is the successor of ASP Golf which was quite popular among German language developers for a long time (the actual ancestor of code golf is Perl Golf). As many golfers switched over to .NET, we decided to migrate this waste of time ^H^H^H^H^H^H^H^H^H^H^H^H^Hmost excellent use of technology to .NET so that the envelope of programming could continually be pushed further.
Sounds interesting, doesn't it? That's what we thought and that's why we ran a tournament at the MVP summit (all English, you can browse it to learn more) to introduce other MVPs to .NET Golf - and whet their appetite to be the host for .NET Golf in their community. If you didn't get a chance to talk to me at the summit, here's what we (German community members, so that there are no misunderstandings) offer: we host the site for you on CodeFairway.NET, and we provide you with the automated test system we have created so that there is little to no overhead for you. Your job: translate the site into your community's native language, and come up with challenges (we can help get you started). My MSN account to get in touch with me: christoph dot wille at alphasierrapapa dot com (also my email alias if you prefer emailing me upfront).
Funny enough at the MVP summit, for the very first time in history of our tournaments, the VB.NET golfers won the tournament hands down. That might have changed if only Karsten and the others would have paid more attention to the sessions 
The leaderboard for the first three looked like this (and yes, the Show link does show the source of the submission - check it out):

It took them quite a while to get on the green, but as with every other tournament I heard something like this: "I only wanted to play till 11:30PM, but at 1:30AM I finally coaxed me to go to bed". Addictive. Even for a simple challenge such as the one played at the MVP Summit:
How can you tell whether three lines of a given length make up a triangle? Some cases are obivious - equilateral triangles, isosceles triangles and triangles governed by the Pythagorean theorem. General triangles are a different matter though. You are now challenged to decide whether a given set of three integers represents the sides of a triangle and indicate this by passing back true, otherwise passing back false to the test application. Please note that "flat" triangles (triangles which have the shorter sides add up to the length of the longer side) do not count as triangles.
The class name for this challenge is Tee, the method name Off. The values for the three sides are passed as a string (never empty, always three values contained) to the Off method, the values are separated by a single space (eg "300 400 5000" which obviously is not a triangle). The values are non-negative integers.
So if you are interested in being the host for your community, get in touch with me. .NET Golf is very popular: currently, Microsoft Austria is using our German codefairway to play a MSDN Connection tournament. Mario just announced it (English).
 |
Friday, September 09, 2005 |
Although the files for this TechTalk repeat are identical to the TechTalk downloads, I noticed that the download location has been moved. For your convenience, here are the direct download links to the three respective files:
 |
Tuesday, September 06, 2005 |
Yesterday, I attended Kevin Cox' talk about database mirroring in SQL Server 2005. The event was organized by the SQL Server User Group Austria in Vienna, with Peter Koen (old UG lead) inviting Kevin, and Jaser Elmorsy (new UG lead) organizing it. Session description for the records: Database mirroring is a new SQL 2005 feature for high availability. What happens if you combine mirroring with other features, like snapshot and clustering? This presentation will teach you the basics of database mirroring, then will discuss some advanced topics for common solutions.
Kevin also pointed us to the SQLCAT blog - CAT being shorthand for Microsoft SQL Server Development Customer Advisory Team. The description as well as Kevin promised that they will be posting demanding scenarios and solutions to those in that very blog.
 |
Tuesday, August 02, 2005 |
On 12th of August, the Austrian .NET community is hosting a one-day conference on security, targeted at developers (no surprise here). The topics for NCC 2005 A include:
- Threat Modeling
- What's new in .NET 2.0 Security
- What's new in SQL Server 2005 Security
- What's new in Windows Vista Security
Quite a nice line-up I'd say. This event is supported by Microsoft Austria, so attending this event is free, except for your time, but I am sure security does warrant a day of your time! Sign up here
 |
Wednesday, July 27, 2005 |
This post is again motivated by last week's Community Bootcamp on ASP.NET 2.0, the CBC05. I presented "Under the Covers - Exploring Internals, Page Lifecycle and the Compilation Mode" from TechEd, using the samples that Simon Calvert provided me with (special thanks fly out to Simon, Ben Miller and Rich Ersek @MS for providing us with material - I know I can be a royal pain in the posterior... sometimes at least).
The talk included a demo of a database-backed virtual path provider (files don't come from the file system but a database, dynamically). Somehow we started talking about how cool it would be if you could test your Web sites without checking them out from source control in the first place - by simply writing a virtual path provider that goes to the repository on demand. I wrote that idea down.
Actually, I didn't think I'd get around to doing that. But yesterday I decided to pester one of my devs on the #develop project, namely Daniel Grunwald. He has implemented the Subversion addin for our 2.0 version, so he had experience with NSvn, the managed API for talking to Subversion. I sent a stripped down version of the vpath provider to him, and asked him to replace database code with NSvn code where appropriate.
It didn't take long, and I had a command-line verified version back, and all I had to do was make sure that it works with ASP.NET 2.0. There were a few problems I ran into (like Subversion is case-sensitive and I didn't want that for the Web scenario). Some of the issues arose simply because client and Web developers have different backgrounds. Talk about path separators. Or directories where you have to drop assemblies.
Now, let's stop talking, let's take a look at the provider in action:
SvnVPathProvider.wmv (3.76 MB)
Want to get your hands on that DemoSiteSvn directory with the current rendition of the SubversionVirtualPathProvider? No problem, just a couple of notes up front on what you should be aware of:
- Only file names are currently treated specially for casing. Ie directories still do react in a case sensitive way.
- The file name cracking code needs to be reviewed. Currently, this is a quick hack.
- appSettings need to be placed in a separate .config file. Reason is that web.config cannot be obtained via a VirtualPathProvider, and thus this file has to be checked out separately. And I don't want to get in the way of automating this by requiring entries in web.config.
- Package it as an assembly, so only the \bin folder needs to be copied to get up and running.
- The VirtualPathProvider requires (at the very least) anonymous access to the repository. Passing security tokens is not implemented.
With those notes out of the way, thanks fly out to the ASP.NET team for providing me with the sample of their virtual path provider in the first place. It has been a tremendous help to get this thing off the ground. And maybe in turn this sample will help others to get started:
SvnVppDemo.zip (972.37 KB)
Installation note: the two DLLs in the system32 folder need to be dropped in the respective folder of your system. Do not place them into \bin. Unless you want to get into trouble, that is.
What is left to say? Oh, the source code, of course! I thought you might be interested in reading it online instead of having to download an almost 1MB-size file first. Here it is (App_Code\SubversionVirtualPathProvider.cs):
using System; using System.IO; using System.Collections; using System.Globalization; using System.Configuration; using System.Text; using System.Web; using System.Web.Util; using System.Web.Hosting; using System.Web.Caching; using NSvn.Core; using NSvn.Common;
namespace ICSharpCode.Web.Providers { public class SubversionVirtualPathProvider : VirtualPathProvider { #region class HashCodeCombiner internal sealed class HashCodeCombiner { // Start with a seed private long _combinedHash = 5381; internal void AddLong(long l) { _combinedHash = ((_combinedHash << 5) + _combinedHash) ^ l; } internal string CombinedHashString { get { return _combinedHash.ToString("x", CultureInfo.InvariantCulture); } } } #endregion
#region class SubversionVirtualFile internal class SubversionVirtualFile : VirtualFile { string fullPath; DirectoryEntry entry; public SubversionVirtualFile(string virtualPath, string fullPath, DirectoryEntry entry) : base(virtualPath) { this.fullPath = fullPath; this.entry = entry; } public override bool IsDirectory { get { return entry.NodeKind == NodeKind.Directory; } } public override Stream concat() { Client client = new Client(); MemoryStream ms = new MemoryStream(); client.Cat(ms, fullPath, Revision.Head);
// .Cat closes the stream, so we have to copy it MemoryStream ms2 = new MemoryStream(ms.GetBuffer()); ms2.Position = 0; return ms2; } } #endregion
public static void AppInitialize() { SubversionVirtualPathProvider provider = new SubversionVirtualPathProvider(); HostingEnvironment.RegisterVirtualPathProvider(provider); } string GetSvnFullpath(string virtualPath) { if (bool.Parse(ConfigurationManager.AppSettings["svnvppStripVdir"])) { // this will break root Webs, StripVdir should be the default however int pos = virtualPath.IndexOf('/', 1); virtualPath = virtualPath.Substring(pos, virtualPath.Length - pos); }
return ConfigurationManager.AppSettings["svnvppRepositoryUrl"] + virtualPath; }
string GetSvnFullpath(string virtualPath, string fileName) { return FixupSvnFullpath(GetSvnFullpath(virtualPath), fileName); }
// Subversion is case sensitive, this we switch the filename here string FixupSvnFullpath(string svnPath, string fileName) { int pos = svnPath.LastIndexOf('/'); string parentDirectory = svnPath.Substring(0, pos + 1); return parentDirectory + fileName; } DirectoryEntry GetEntry(string virtualPath) { Client svnClient = new Client(); string fullPath = GetSvnFullpath(virtualPath); int pos |