 |
|
 |
 |
Friday, February 08, 2008 |
Yesterday, we found ourselves at the receiving end of an attack against one of our German Wikis that are running the ScrewTurn Wiki software. Turns out that it was a security issue even with the then latest version 2.0.23. Dario Solera - the maintainer of ScrewTurn - acted real fast when I informed him about the root cause of the attack and released v2.0.24 yesterday night.
Please download and upgrade immediately! The issue is being actively exploited (zero day if you so will).
 |
Thursday, December 13, 2007 |
 |
Friday, November 30, 2007 |
I have posted an updated version
Given my plans to rather sooner than later upgrade my server to IIS7, I am currently switching all applications to ASP.NET 2.0 in preparation of this move. But there was nGallery, which I used all over the place when I needed a photo gallery...
Today I decided it was about time to do something about it, and gave converting nGallery to .NET 2.0 a try (actually all the projects target .NET Framework 3.5). Turns out it took me roundabout two hours for this whole endeavour. To save everybody else time, here is my VS2008 solution tree:
nGalleryTNG.zip (2.92 MB)
What is changed compared to the original nGallery 1.6.1 for ASP.NET 1.1? Here is a somewhat complete laundry list:
- Converted it to a Web Application project
- Placed all third party source code in the ThirdParty folder. That way I can always change and recompile if necessary.
- Took all static images from the \photos directories and put them into \images. No more mixing the photo handler & photo cache with the Web site's images.
- The album handler is now being abused in Application_BeginRequest, plus it now uses RewritePath. Fixes the darn Server.Transfer errors.
- Moved the configuration of nGallery from the data folder to App_Data. Other than that: no configuration changes.
I did not switch to ASP.NET 2.0 master pages, it still uses the old user control approach. But after all, I only needed it in a working fashion for 2.0+.
Note: I only tested the XML-based storage because that's how I use nGallery. The SQL-storage has received no testing whatsoever!
Download Web site files only: nGalleryTNG_WebSite.zip (924.39 KB)
I posted a version of the Really Simple Guestbook - With XLinq for Orcas Beta 2 earlier on this blog. Today, I updated this small application for VS2008 RTM. The following changes are incorporated:
- It is now a Web project, no longer file system based
- It includes AIP for form spam protection (aka captcha)
I decided to not include the Microsoft Anti-Cross Site Scripting Library V1.5, that is up to the reader if additional security is required (note: you'd have to add this to AddEntry.aspx's logic of inserting new guestbook entries).
Download: XlinqGuestbook.zip (165.53 KB), License: BSD
 |
Friday, November 02, 2007 |
XSSDetect is a static code analysis tool that helps identify Cross-Site Scripting security flaws found within Web applications. It is able to scan compiled managed assemblies (C#, Visual Basic .NET, J#) and analyze dataflow paths from sources of user-controlled input to vulnerable outputs. It also detects whether proper encoding or filtering has been applied to the data and will ignore such "sanitized" paths. Download
 |
Tuesday, October 30, 2007 |
 |
Monday, October 15, 2007 |
Been on holidays, at conferences (eg last week Ask The Experts @ XTOPIA in Berlin), and worked on various projects - a couple of reasons it was rather quiet lately in this blog.
Yesterday I decided I needed a simple guestbook application for a to-be-developed private Web site, and because I didn't find anything that fit my needs I decided to write one myself with the goal of (ab)using XLinq in the course of this endeavour:
Guestbook_XLINQ.zip (7.09 KB)
Caveat emptor: I am no designer (surprise!). But thanks to no design it should be easy for you to add your own design. However, as this month's MSDN magazine is all about security, I decided to make the application production-ready security-wise. You'll find a lot of parsing plus XSRF protection (note: this version does not check for integer overflow in calculating the start row).
Missing features: this guestbook is not prepared for localization, nor does it use a control-based approach (where you drop those in your pages and get an in-place guestbook).
Update a version of this application for VS2008 RTM is available here.
 |
Thursday, May 24, 2007 |
I have been doing some sprucing up of SharpDevelop's Web offerings today - namely the code converter. Up until today, you only could convert syntactically valid classes. Recently, Daniel implemented the SnippetParser class, which is now in use for the snippet converter (C# to VB.NET, VB.NET to C#). Note: the Web service for code conversion does support both class and snippet conversion, a Windows client sample is available for the former.
Also new (just completed a few minutes ago) is the code formatter: it uses the highlighting engine from SharpDevelop's text editor to HTML-ize a bunch of formats: ASP/XHTML, BAT, Boo, Coco, C++.NET, C#, HTML, Java, JavaScript, Patch, PHP, TeX, VBNET, XML. Again, there is a Web service available, as well as a sample using the service. This offering is built upon the HtmlSyntaxColorizer sample that can be found in SharpDevelop revisions > 2522 (currently only on the build server)
I am sure that both the snippet converter as well as the code formatter are welcome additions. Spread the word! After all, it's free.
 |
Thursday, April 26, 2007 |
Bill Staples put together a post on what's new in IIS7 Beta 3. He also talks about the all-new IIS7 FTP server (which I knew about for a long time - I had hoped Beta 3 would be available for my MSDN Briefing in Vienna last month, but no such luck). Also, he mentions the GoLive! license for IIS7.
 |
Tuesday, February 06, 2007 |
Nikhil has updated his controls for ASP.NET AJAX 1.0. Download here
Quote from his blog (so you know why you should go and download them):
- UpdateHistoryThis is a non-visual control that allows you to add history entries to the browser's navigation stack selectively for some post-backs, and not for some others. This helps fix the back button to make it work, and allows you to implement Ajax patterns such as "logical navigation" and unique URLs.
- StyledUpdatePanel A simple derived UpdatePanel that adds CSS class semantics. A simple addition, but a useful feature, nevertheless, that didn't make the feature cut.
- AnimatedUpdatePanel Another derived UpdatePanel that displays new content using a variety of animations or effects: slides, wipes, cross-fades as well as a visual highlight. This allows you to implement the "visual notification" Ajax patterns such as the one second spotlight and one second mutation.
 |
Wednesday, January 03, 2007 |
I have been re-awarded MVP for Visual Developer ASP/ASP.NET.
 |
Wednesday, November 22, 2006 |
I admit it: I am a regular reader of the event log. In doing so, I came across an error message last week that I rarely get to see - invalid Viewstate:

Now, that wouldn't be a problem, usually at least. However, in this special case I went WTF? when I looked at the description more closely, especially at the PersistedState information: PersistedState: a Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Mailer: EMUmail 4.5 Subject: jam n bcc: <list of addresse removed by me /> comes from the loin in the middle of the back of the pig. t is a lean meaty cut of bacon, with relatively less fat compared to other cuts. iddle bacon is much like back bacon daa6c5071189f202ceb370d0e9d38c33 .
Come again - spam in Viewstate? What would be the point of this? After some research together with Alex I came across this article: Interesting Crack Attempt to Relay Spam (a more detailed article is available too: Form Post Hijacking). How did I manage to not take notice of this attack vector any earlier I don't know, but I have to admit that the idea is pretty clever.
Counter-measures in general? Well, either don't allow users input in the headers at all, or vet the form fields for carriage return / line feeds. Note that I did not verify if any of the available mail components for .NET would be actually susceptible to this kind of attack.
 |
Wednesday, November 08, 2006 |
From the nuggets page: Don't have the time to read a 10-page how-to article or watch a full length webcast? Try an MSDN Nugget, a webcast that takes you step-by-step to discovering new functionality or exploring a hot developer topic, all in 10-15 minutes. If you haven't seen this yet, check it out!
 |
Wednesday, June 21, 2006 |
Today, Daniel held a talk comparing AJAX frameworks for ASP.NET. He limited the scope to indirect frameworks, which means: those AJAX frameworks extend ASP.NET, and you don't necessarily need to know much about AJAX. On his Web site, you will find a comparison of AJAX frameworks for ASP.NET (direct as well as indirect).
 |
Tuesday, June 20, 2006 |
As promised, here is the list of links / articles / samples that I used for preparing my talk "Build Provider in ASP.NET 2.0":
Hope you will find those useful.
 |
Monday, June 19, 2006 |
Half an hour ago, I completed my talk "Windows Workflow Foundation & ASP.NET 2.0". As promised, here is the list of links to sites / documents that I used to prepare this talk & accompanying samples.
Also, see my last post on ASP.NET PageFlow CTP. This was the last part on "future technologies".
Update A foto from my talk on Monday (debugging a workflow in ASP.NET):

 |
Tuesday, June 13, 2006 |
Yesterday night, I watched a WebCast from TechEd Boston - "An Overview of ASP.NET and Windows Workflow Foundation". What this innocuous title hid was the fact that Kashif Alam (PM in the Developer Division) was presenting vNext features for ASP.NET workflow integration: Page flow (PageFlow) as well as UI flow (UIFlow), plus the accompanying extensibility model.
What do those two separate approaches provide? Well, you get MVC (model-view-controller) support for same-page (UIFlow) as well as cross-page (PageFlow) scenarios. Pretty neat was the included "Choosing the right solution" slide to get an idea what's in store:
| Task |
<asp:wizard...> |
PageFlow |
UIFlow |
| Single page |
x |
|
x |
| Multiple pages |
|
x |
|
| State when close browser |
|
x |
x |
| Integrate with Enterprise WF |
|
x |
x |
| Client support |
|
x |
x |
| Built-in navigation UI |
x |
|
|
| Extensibility to other controllers |
|
x |
x |
As developers, we will get our hands on this later this year in the form of the "ASP.NET PageFlow CTP" (at least that's the current name), and it will be deployed with Orcas.
 |
Monday, March 20, 2006 |
 |
Sunday, February 19, 2006 |
On my flight to Seattle today (or yesterday, depending on the time zone) I started to read Professional ASP.NET 2.0 Security, Membership, and Role Management by Stefan Schackow. The book definitely is a must-have for every ASP.NET developer, even if you decide to read one chapter only: A Matter of Trust (#3). This one will save you loads of time when you have to deploy an application into non-full trust environments. However, the other chapters are worthwhile too, like #2 which details exactly which identity is used when by what part of the engine. Bottomline: highly recommended reading.
 |
Wednesday, January 18, 2006 |
Yesterday, I picked up on an old code piece of mine - sending images to the client via an HttpHandler. Why in the world would you implement that with a handler when there is http.sys kernel mode caching? Well, I had a few unique constraints:
- the images had to live outside the Web root and any of its vroots
- the image names had to be concealed because the naming would give away information, and renaming the images prior to publishing on the Web was out of the question
Now, a common approach to sending images from a certain directory (leaving requirement #2 by the wayside for the moment) would be this: image.aspx?image=iamthebest.jpg
So what is wrong with this approach? First and foremost using an ASP.NET page. The page lifecycle is a drain on performance and throughput, because you simply don't need it. That sorts out why I chose to go with an HTTP handler.
Secondly, somebody could DOS your server. You heard me right. For the background, check the article Trap Alert: Files that aren't. A .NET version (managed C++) of this checker can be found in this download (the article Dateityp-Ermittlung in Managed C++ is only available in German).
How do you get around this issue? Well, how about reading the directory up front, and instead of having the filename in the URL, send the hash! When the image is requested, take the hash and look up the corresponding file, presto. In addition you get one security feature for free: no directory traversals can be hidden in your code.
When I uncovered the code yesterday, I decided to rewrite it for more general use. So what do you get?
- The ImageCacheControls project: it contains the ImageCache class, which does most of the heavy lifting. In addition, you get an ImageCacheControl server control, as well as the implementation of the HTTP handler. (Don't forget to check out the Readme.txt for the latest on feature set and known issues)
- The Web project: a rather simple Web site with demo files in it. The file I want to direct your attention to is Image.ashx. This is the one file - aside from the control project binaries - that needs to be copied to your projects to get started with ImageCache. Note that I made it easy to work with C# (default) or VB.NET.
Usage of ImageCache is demonstrated in default.aspx.cs plus the source code of default.aspx (design time of the control does not work, known issue).
The code behind looks like this (CreateMapping loads the directory contents, initializes the hash to file name map, stores it into the cache):
using ChrisOnNET.ImageCache;
public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { // normally, this would be done in global.asax ImageCache.CreateMapping("demo", Server.MapPath("~/TestImages/"));
// the DIY approach to rendering the image tag string testHash = ImageCache.GetHashForFile("026.jpg", "demo"); Response.Write("<image src=\"Image.ashx?bucket=" + "demo" + "&image=" + Server.UrlEncode(testHash) + "\" />");
// the elegant approach to rendering the image tag Response.Write("<image src=\"" + ImageCache.GenerateUrl("036.jpg", "demo") + "\" />");
// see HTML source for server control approach (Design time not working, known issue) } }
Rendering Image tags in Page_Load isn't nice, but after all it is only intended to show the functionality. Most likely you are going to use the declarative ImageCacheControl anyways: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <%@ Register Assembly="ImageCacheControls" Namespace="ChrisOnNET.ImageCache" TagPrefix="cc1" %> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> <br />Using the ImageCacheControl: <cc1:ImageCacheControl ID="ImageCacheControl1" Bucket="demo" FileName="026.jpg" runat="server" /> </div> </form> </body> </html>
That's basically it. Let me know what you think.
ImageCacheTakeOne.zip (59.55 KB)
 |
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.
 |
Thursday, December 29, 2005 |
 |
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!
 |
Sunday, November 27, 2005 |
Next week, I will be in Rosenheim, Germany for the ADC 2005. I'll be teaching the Visual Studio 2005 Team System Hands-on workshop (Tuesday as well as Friday), plus doing two talks during the main conference: IIS 7 and ASP.NET 2.0 Health Monitoring. See you there!
 |
Monday, November 14, 2005 |
You need: Visual Studio 2005, IIS 6.0 and Visual Studio 2005 Web Deployment Projects (Beta Preview). Of course, the .NET Framework 2.0 should be installed.
The site has one simple page: Convert.aspx (C#, separate code file):

As you can see, this page is being run with the ASP.NET Development Web Server. Also works fine with IIS 6.0.
Next, let's add a deployment project to our Web project:

Build it, and in IIS, create a new application and map it to the Debug directory. Execute the page:

Oopsie, what the hell happened here? The answer can be found by digging into the Temporary ASP.NET Files directory:

Let's have a look at the generated vs precompiled assemblies in ILDasm:

So what's the difference? Well, it happens that by default on-demand compilation and precompilation behave differently in the way the pages (page classes) are stitched together. In one case we have a quasi-random name, and in the other we have the class name as it was set in our Convert.aspx - Convert. And this rather obviously clashes with System.Convert (I have a certain talent on picking about the single problematic name).
Why is the Convert name retained? Look in Property Tabs for the deployment project:

By default "Allow this precompiled site to be updatable" is checked - which after all is very useful. But not in this specific case where my Convert class clashes with System.Convert...
In my blog entry Crashing Visual Studio 2005 for Fun I described how to crash Visual Studio 2005. Scott Guthrie followed up, and since then I was in permanent contact with team members. After some research, it turned out that it (a) was seemingly reproducible only on my machine, and (b) likely a tooltip issue.
What is going? Well, my machine is equipped with a Matrox P750 and has three monitors attached, spanning a single 3840x1024 "display". This strechted single display is managed by Matrox PowerDesk-HF, and it comes with a couple of desktop settings to make applications play nice on three physical monitors. One of those options is "Prevent tooltip spanning in strechted mode":

What does this option do? Imagine that I have an application full screen on the middle monitor - without that option turned on, tooltips "overflow" to the monitor to the right (you only see the background image in this screenshot, but that is the 3rd monitor):

Now guess what - once I turn that option on, VS05 crashes the way I described in my previous blog entry. It took me a couple of reboots, configuration from scratch and quite some testing to finally figure out the root cause for this crash.
 |
Sunday, November 13, 2005 |
 |
Thursday, November 10, 2005 |
I just finished a Web-based C# to VB.NET converter for .NET 2.0. It took me about half an hour and 20 lines of code. How come? Well, Daniel (#develop 2.0 PM) did a video on NRefactory, which is at the heart of #develop's parsing infrastructure. I took some of his demo code plus some of #develop's internal code converter, and put it into a ASP.NET 2.0 page. Presto, that easy if you can stand on the shoulders of giants.
Oh, and I actually put it online, here is the link: C# to VB.NET converter (you can find the source code for a simpler VB.NET implementation of the converter here).
 |
Tuesday, November 08, 2005 |
Now, I did not set out to crash it intentionally, but at least it is fully reproducible. What did I do? Well, I wanted to build a site based on the code I wrote in the blog entry Writing a Subversion-backed VirtualPathProvider for ASP.NET 2.0. So I created a new directory for the site, and simply put the code from the download into a subdirectory (which already exists in the zip file):

Of course I went ahead and opened MyNewWebSite in Visual Studio 2005:

Nothing unexpected so far, I can expand all directories just fine in Solution Explorer:

However, as soon as I hover over SubversionVirtualPathProvider.cs, Solution Explorer goes grey. Totally grey. As in no icons, no tree, no nothing. So I File / Exit Visual Studio 2005 (saying No to saving the solution), and kabooom, here is my friend the error reporting tool:

Oh, and btw, an empty App_Code directory won't do the trick.
 |
Sunday, October 16, 2005 |
The ASP.NET 2.0 Deployment Guide is a reference for web hosters who are interested in adding ASP.NET 2.0 to their existing Windows hosting service. Besides improving developer productivity, ASP.NET 2.0 also provides benefits for hosted environments, including support for shutting down inactive applications and locking down rogue applications. Enhanced health monitoring configuration can be used to set thresholds and severity levels for monitoring the health of ASP.NET.
 |
Friday, October 14, 2005 |
My dedicated server box not only serves Web applications (such as this blog), it also handles mail for the respective domains. This means I have to deal with spam. Which on one hand is nice because I can do whatever I please: drop mail based on whatever criteria I set up, and use whatever filtering software I need.
This is how the NoSpamToday! SMTP Proxy found its way on my box. I simply got tired of maintaining my (rather old) standalone SpamAssassin installation, and dealing with MailEnable's integrated but not chained RBL / SPF / virus scanning (by not chained I mean that those filters are evaluated separately, not like SA, where all filters[rules] are weighted and evaluated as a whole).
Because I only have one box, I had to resort to relocate MailEnable to port 45, so that NoSpamToday! could listen on 25 and forward to MailEnable if appropriate (*). I did configure SMTPS previously (port 465 redirected to localhost:45 via stunnel), so standard users could deliver their mail directly to MailEnable instead of having their outgoing mail scanned by the proxy.
But what about my Web applications? Initially, those were sending to localhost directly, and as such I had a relaying exception set up in MailEnable. This one had to go, obviously. So how can applications deliver mail to the mail server via the proxy? SMTP authentication is necessary for this to happen.
But this doesn't solve the whole issue, it opens a can of worms, performance-wise. The problem is, every single application (Community Server, dasBlog, Gemini, ...) assumes that your SMTP server listens on port 25. Wrong. That's the proxy. And that's a problem: all local outgoing email from those applications is scanned by antivirus and antispam filters. And that's completely wasting CPU resources. As well as adding to # of addresses accepted by the backend mailserver, driving up the licenses that would be needed for NoSpamToday! (**).
Call to action: Implement not only SMTP authentication in your applications, but also make the SMTP server port configurable. I'm guilty as well.
(*)

(**)

 |
Wednesday, October 05, 2005 |
You only have to wait till the others do all the typing: Paul and Plip are writing about the Web Deployment Projects feature that we were shown today at the AspInsiders summit. Cool stuff that should be in the hands of everybody by the time VS05 launches.
 |
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, September 25, 2005 |
I already have one box (the Shuttle XPC) that is running Windows Server Codename Longhorn Build 5219. Because it wasn't all that much of a hassle when compared to Beta 1 of Windows Vista, I decided to set up Longhorn on my laptop - and try to work with that installation for a week, while I am in Seattle for the MVP & AspInsiders summits. Boy did I end up with an installation marathon...
Lessons learned in this Sunday's "don't try this at home kids" department:
- Don't assume that ATI drivers for your IBM X31 will install on Longhorn. They refuse, making for rather crappy UI performance. By the way, on failing, setup suggests to install a VGA driver first.
- None of the network adapters were found - neither the onboard LAN, nor the onboard WLAN. When you peek into Computer Mangement, it is your guess which of the two "Ethernet Controller" is which.
- Don't only update the driver for one, even if it is the LAN one. Your ISA 2004 client installation will mysteriously fail. After installing drivers for all LAN equipement, it just works.
- Minor annoyance: the OS-provided sound driver produces hisses et al. Not too bad, but annoying if you plan to watch loads of Channel 9 movies. Your guess is correct: the vendor-provided driver refuses to install.
- No standby. That sucks royally.
- You learned about that in my previous post - no .NET 1.1 for you by default.
- Installing VS can be so much fun, especially if MSXML 6.0 refuses to install as part of the default install. Doing it separately works so much better. And the "Locate File" dialog for the VM driver irritated me only for the better part of a minute...
- Before installing the Atlas VSIs, you better start VS at least once. Otherwise the Atlas installation will fail. Only mildly interesting.
- Do I need to mention that Virtual PC networking doesn't work? That one didn't change for the better, which will make me dual boot into XP.
On a different note: default installs of 5219 have a blank password for Administrator. And IIS 7 is installed by default, which really baffled me. I'm so trained to enable features after install that at first I was thinking it was not part of the bits I got...
 |
Tuesday, September 20, 2005 |
Nikhil demonstrated it last week at the PDC, now he released the new version of the Web Development Helper to the public. Read more about the exciting new features here.
 |
Friday, September 16, 2005 |
The day started out with one of those famous spoof videos - this time about a "variation" of Windows error reporting, dubbed WE-SYP (we share your pain). Error reporting tied to a - let's call it - "multimedia" chair. Fun to watch.
Right after that, Bob Muglia showed off what we can expect from Windows Server in the next couple of year. Windows Server 2003 Compute Cluster Solution was demoed together with Excel Services - impressive. TxF (transactional NTFS) wasn't any less exciting, just like the identity solutions - and, of course, IIS 7.0. We got the bits for the latter today.
Sessions I attended today:
- Windows Communications Foundation ("Indigo"): A Deep Dive into Best Practices Using the Windows Communications Foundation
- ASP.NET: Future Directions for Developing Rich Web Applications with Atlas (Part 2)
- ASP.NET: A Sneak Peek at Future Directions in Web Development and Designer Tools
- Windows Vista & "Longhorn" Server: Under the Hood of the Operating System—System Internals and Your Application
- ASP.NET: Deep Dive into the ObjectDataSource Control
The under the hood session for Longhorn server had one interesting tidbit - they aim to require mandatory signing for kernel mode drivers on x64 platforms - bye bye kernel root kits!
Bradley Millington quite overshot his allocated timeslot for the ObjectDataSource control, but he covered interesting areas: filtering and master details, custom sorting and paging, updates inserts deletes as well as transactions and caching. Seeing realistic examples is a welcome change. A good place for you to start: the Advanced Data Scenarios section of the Quickstarts. (Note: those links point to http://beta.asp.net, and I don't think that Whidbey docs will be up and running there forever, given that "Orcas" starts appearing on the horizon).
 |
Tuesday, September 13, 2005 |
Want to know what Atlas is all about? On the Atlas site you will find hands-on labs, live quickstarts demoing Atlas features, documentation, and VSIs for creating your own Atlas apps with Visual Studio 2005. What are you waiting for? Check it out now!
The PDC today officially kicked off with a keynote by Bill Gates. To me, the more interesting parts came later in Jim Allchins keynote: Atlas, Windows Communication Foundation, Windows Presentation Foundation as well as C# 3.0 & LINQ. However, Office 12 does look very promising too. Can't wait to get my hands on that beta (never expected to say that about Office, ever).
In the afternoon, I attended the following breakouts:
- Behind the Scenes of Visual Studio 2005 Team Foundation Server
- Windows Server “Longhorn”: What's New for Developers
- Windows Presentation Foundation ("Avalon"): A Lap around the Windows Presentation Foundation
Looking forward to tomorrow, because Windows Workflow Foundation will be revealed at the keynote (aka general session).
 |
Tuesday, August 16, 2005 |
From the summary of this security practice: This module presents a set of consolidated practices designed to address ASP.NET version 2.0 security issues. The answers and recommendations presented in this module are tight distillations designed to supplement the companion modules and additional guidance. The practices are organized by various categories that represent those areas where mistakes are most often made.
Security Practices: ASP.NET 2.0 Security Practices at a Glance
 |
Wednesday, August 10, 2005 |
Want to test your Web site with that other browser? You know, the one that ships with the operating system? Here is how to do that. Start by right-clicking on the page you want to open:

In the Browse With dialog box, you can now choose which browser to use this time only, or by clicking Set as Default, use it for all your future Ctrl+F5 endeavours:

Sometimes, it might be handy to not have VS.NET pick a dynamic port each and every time it starts Visual Web Developer Web Server (aka ASP.NET Development Server or, as it was called back in the old days, Cassini). There is an easy way to get a fixed port when you press Ctrl+F5. First step is to select the Web project in Solution Explorer:

Next, go to the Properties window (DO NOT right-click and choose Property Pages - you will end up somewhere entirely different):

As you can see, I already switched "Use dynamic ports" to False, and in this case, I chose to stick with the default provided port number. When is this port-setting useful? When you automate tests, for example.
 |
Monday, August 08, 2005 |
 |
Wednesday, August 03, 2005 |
Scott Guthrie has written a blog entry about how to make this happen. Really, really easy to do.
 |
Tuesday, August 02, 2005 |
The Microsoft ASP.NET Developer Center has the Provider Toolkit online. It sports the Access Provider as a C# class library project for download!
 |
Friday, July 29, 2005 |
One thing I didn't get around to demo at last week's CBC05 is the usage of profiles to remember and subsequently set the culture on ASP.NET pages. That's why I am documenting it now.
To get started, we need to have a profile that stores the user's preferred culture. So your profile in web.config looks could like this: <profile enabled="true" defaultProvider="myProfile"> <providers> <add name="myProfile" type="System.Web.Profile.SqlProfileProvider" connectionStringName="NWConn"/> </providers> <properties> <add name="Culture" type="String" defaultValue="en-US" /> <add name="Theme" type="String" /> </properties> </profile>
The Culture profile setting is changed via a simple (hard-coded) dropdown list in default.aspx, which also displays a greeting pulled from a localized global resource, the culture code for verification purposes, as well as the current time formatted according to the respective locale:

The code for the button in default.aspx.cs is rather basic as you would have expected:
protected void Button1_Click(object sender, EventArgs e) { Profile.Culture = DropDownList1.SelectedValue;
// really nasty redirect to go back to this back and see the effect Response.Redirect(Request.Path + "?" + Server.UrlEncode(DateTime.Now.ToLongTimeString())); }
The real magic for setting the culture so that formatting is done correctly, as well as the right resources being displayed, is done in a custom HttpModule, which needs to be registered in web.config: <httpModules> <add name="myProfileModule" type="ICSharpCode.Web.ApplyProfileToPageModule" /> </httpModules>
This guy lives in App_Code\ApplyProfileToPageModule.cs, and looks like this:
using System; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using System.Threading; using System.Globalization;
namespace ICSharpCode.Web { public class ApplyProfileToPageModule : IHttpModule { public void Dispose() { // currently, does nothing }
public void Init(HttpApplication context) { context.PreRequestHandlerExecute += AppPreRequestHandlerExecute; }
private void AppPreRequestHandlerExecute(object sender, EventArgs e) { Page p = HttpContext.Current.Handler as Page;
if (null != p) { ProfileCommon pc = (ProfileCommon)HttpContext.Current.Profile;
string cultureName = pc.Culture;
CultureInfo culture = new CultureInfo(cultureName);
Thread.CurrentThread.CurrentUICulture = culture; Thread.CurrentThread.CurrentCulture = culture;
// You can set the Theme exactly the same way, shown below: // p.Theme = pc.Theme; } } } }
In PreRequestHandlerExecute, I can access the profile, and go ahead and read the culture that is defined. Then all you need to do is set the CurrentUICulture as well as CurrentCulture of the CurrentThread. Done.
By the way, this event is also your ticket to set the Theme for a Page - if you have defined the user's preferred theme in her profile. Neat way of doing this.
LocalizationModule.zip (6.09 KB)
 |
Thursday, July 28, 2005 |
Did you know that the Membership API isn't limited to being used inside ASP.NET 2.0 applications? That you can also use it in say a Console application? This is actually very useful, because that spells automated administration for me.
In order to demo this, I set out and created a very simple Web application that lists users registered with the Membership system:

This simply calls Membership.GetAllUsers() and we are set. More interesting is web.config (partial view): <connectionStrings> <add name="NWConn" connectionString="Data Source=cbc05vpc\cbc05;Initial Catalog=Northwind;User=sa;Password=P@ssw0rd"/> </connectionStrings> <system.web> <membership defaultProvider="myMembership"> <providers> <clear/> <add name="myMembership" applicationName="DemoApp" connectionStringName="NWConn" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, ..." /> </providers> </membership>
This is using the stock SqlMembershipProvider, and stores data inside the Northwind database. Pretty vanilla, except for one important attribute: applicationName. Because one Membership database can hold accounts for multiple applications, we need to define the name here unless we want to end up with guessing that name for the console application.
Now let's switch to the Console application. It obviously needs to reference System.Web.dll:

Secondly, it needs an App.Config file (this time, in full glory): <?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="NWConn" connectionString="Data Source=cbc05vpc\cbc05;Initial Catalog=Northwind;User=sa;Password=P@ssw0rd"/> </connectionStrings> <system.web> <membership defaultProvider="myMembership"> <providers> <clear/> <add name="myMembership" applicationName="DemoApp" connectionStringName="NWConn" type="System.Web.Security.SqlMembershipProvider, System.Web, ..." /> </providers> </membership> </system.web> </configuration>
As you can see, I simply copied its contents verbatim from the previously shown web.config. All we now need is to access the Membership API inside our application:
using System; using System.Collections.Generic; using System.Text; using System.Web.Security;
namespace TheConsoleApp { class Program { static void Main(string[] args) { MembershipUserCollection muc = Membership.GetAllUsers(); foreach (MembershipUser mu in muc) Console.WriteLine(mu.UserName + " " + mu.Email); } } }
Surprise, surprise - it works as expected:

Done.
MembershipEverywhere.zip (19.28 KB)
 |
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 = fullPath.LastIndexOf('/'); string parentDirectory = fullPath.Substring(0, pos); string entryName = fullPath.Substring(pos + 1);
try { DirectoryEntry[] entries = svnClient.List(parentDirectory, Revision.Head, false); foreach (DirectoryEntry entry in entries) { if (0 == String.Compare(entry.Path, entryName, true)) return entry; }
return null; } catch (SvnClientException ex) { if (ex.ErrorCode == 160013) // parent directory not found return null;
throw; } } public override bool FileExists(string virtualPath) { DirectoryEntry e = GetEntry(virtualPath); if (e != null) return e.NodeKind == NodeKind.File;
return Previous.FileExists(virtualPath); } public override bool DirectoryExists(string virtualDir) { DirectoryEntry e = GetEntry(virtualDir); if (e != null) return e.NodeKind == NodeKind.Directory; return Previous.FileExists(virtualDir); } // Obtain the file. This will only be called if the hash that we return is // different than that the runtime holds on to as a cached indicator. public override VirtualFile GetFile(string virtualPath) { DirectoryEntry e = GetEntry(virtualPath); if (e != null) return new SubversionVirtualFile(virtualPath, GetSvnFullpath(virtualPath, e.Path), e); // Default to the previous implementation return Previous.GetFile(virtualPath); } /// /////////////////////////////////////////////////////////////// /// Return a hash value indicating a key to test this file and dependencies have not been /// modified public override string GetFileHash(string virtualPath, IEnumerable virtualPathDependencies) { HashCodeCombiner hashCodeCombiner = new HashCodeCombiner(); ArrayList unrecognizedDependencies = new ArrayList(); foreach (string virtualDependency in virtualPathDependencies) { DirectoryEntry e = GetEntry(virtualDependency); if (e != null) { hashCodeCombiner.AddLong(e.Size); hashCodeCombiner.AddLong(e.CreatedRevision); } else { unrecognizedDependencies.Add(unrecognizedDependencies); } } string result = hashCodeCombiner.CombinedHashString; if (unrecognizedDependencies.Count > 0) { result += Previous.GetFileHash(virtualPath, unrecognizedDependencies); } return result; } /// /////////////////////////////////////////////////////////////// /// The cache dependency is a specialized object that means that the runtime /// can perform file monitoring and change notifications directly public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart) { // This VPP does not create CacheDependencies DirectoryEntry e = GetEntry(virtualPath); if (e != null) return null; return Previous.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart); } } }
 |
Tuesday, July 26, 2005 |
Script Callbacks were also part of my "Advanced ASP.NET 2.0" day at the Community Bootcamp 2005 in Bad Ischl. Aside from showing the usual callback sample, I decided that something more useful was in order. That is why I went a tad further by showing off the controls introduced in the RefreshPanel GotDotNet workspace. I came across those a while back when reading articles on Bertrand Le Roy's blog:
Of course we did labs on CallbackProxy and RefreshPanel, the latter one is described in this blog entry (again, a streamlined version of the lab done by Alexander Schoeppl).
Let's start with the result we wanted to achieve:

The render date only acts as a "proof" that no Postback happened, the dropdown control lists all customers in Northwind and is also populated up front. The GridView control, however, is filled using out of band calls. Instead of hacking your own ugly JavaScript, we did that using the RefreshPanel control.
Step 1: Copy RefreshPanel.dll
First, copy RefreshPanel.dll to the \bin directory of your site. You can get it here.
Step 2: Set up a connection string in web.config
We will use that later both in markup and code beside file: <connectionStrings> <add name="NorthwindConnectionString" connectionString="Data Source=cbc05vpc\cbc05;Initial Catalog=Northwind;User=sa;Password=P@ssw0rd"/> </connectionStrings>
Step 3: ShowCustomerOrders.aspx
Basically, "organized" in three sections (separated by a blank line): <%@ Page Language="C#" AutoEventWireup="true" CodeFile="ShowCustomerOrders.aspx.cs" Inherits="Show_Customer_Orders" Title="Callback Demo" %> <%@ Register TagPrefix="rp" Namespace="MyControls.RefreshPanel" Assembly="RefreshPanel" %> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> Render Date: <asp:Literal ID="Literal1" runat="server"></asp:Literal> <br /> <asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="SqlDataSource1" DataTextField="CustomerID" DataValueField="CustomerID"> </asp:DropDownList> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT [CustomerID] FROM [Customers]"> </asp:SqlDataSource> <rp:RefreshButton ID="MyButton" RefreshPanelID="RFPanel1" runat="server" ClientRefreshArgument="this.form.DropDownList1.options[this.form.DropDownList1.selectedIndex].value" Text="Show Orders"/> <br /> <rp:RefreshPanel runat="server" ID="RFPanel1" OnRefreshing="FillData"> <asp:GridView ID="GridView1" runat="server"> </asp:GridView> </rp:RefreshPanel> </div> </form> </body> </html>
Register imports the RefreshPanel control suite for us, the Label and DropDown are also very straightforward. The RefreshPanel control itself contains a single GridView control, and it is linked to the server-side method FillData which we will examine in the next step. The RefreshButton is responsible for activating the out of band call back to the server - that's also where we get the value from the dropdown control, and pass it as an event argument to FillData.
Note that the control names are hardcoded, in the real world we'd build that string dynamically, because otherwise we'd get into trouble, eg with master pages.
Step 4: ShowCustomerOrders.aspx.cs
Page_Load is trivial, we are only interested in FillData:
public void FillData(object sender, RefreshingEventArgs e) { string connectionString = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ToString();
string sqlCmd = "Select * from Orders where customerID = @CustomerID";
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(sqlCmd, conn); cmd.Parameters.AddWithValue("@CustomerID", (string)e.EventArgument);
conn.Open(); SqlDataReader reader = cmd.ExecuteReader();
GridView1.DataSource = reader; GridView1.DataBind(); reader.Close(); conn.Close(); }
No magic in our code, but: RefreshPanel takes care of giving us a GridView control to work with, and shipping the resulting HTML to the client - and inserting it into the page. Very, very neat indeed.
CallbackDemo.zip (43.51 KB)
 |
Monday, July 25, 2005 |
On Friday, it was my turn as speaker at the Community Bootcamp 2005 aka CBC05. One of the topics at hand was "The Provider Model", with a focus on Membership providers. Those are the ones most likely being extended / written from scratch, and we did an exercise in that very area: Extend the SqlMembershipProvider to audit successful and failed logins similar to *nix. The solution I present today is a streamlined solution programmed by Alexander Schoeppl, one of the attendees.
Step 1: Create the table CREATE TABLE [dbo].[myLoginAuditing]( [username] [varchar](255) NOT NULL, [numberofSuccessfulLogins] [int] NOT NULL, [numberofFailedLogins] [int] NOT NULL, [lastFailedLogin] [datetime] NOT NULL, [lastFailedLoginIP] [varchar](15) NOT NULL)
Step 2: Create the stored procedure create procedure myLogUserVisit( @username as Varchar(255), @success as int, @lastfailedLoginIP as varchar(15)) as IF ( EXISTS ( SELECT username FROM dbo.myLoginAuditing WHERE username = @username ) ) BEGIN if (@success = 1) Begin update myLoginAuditing set numberofSuccessfulLogins = numberofSuccessfulLogins + 1 where username = @username End else begin update myLoginAuditing set numberofFailedLogins = numberofFailedLogins + 1, lastFailedLogin = GetDate(), lastfailedLoginIP = @lastFailedLoginIP where username = @username end END ELSE BEGIN if (@success = 1) Begin insert into myLoginAuditing (username, numberofSuccessfulLogins, numberoffailedlogins, lastfailedlogin, lastfailedloginip) values (@username, 1, 0, '01.01.1900', '') End else begin insert into myLoginAuditing (username, numberofSuccessfulLogins, numberoffailedlogins, lastfailedlogin, lastfailedloginip) values (@username, 0, 1, GetDate(), @lastfailedLoginIP) end END
Alexander did a smart thing - he looked at the various aspnet* sp's.
Step 3: Write the Membership provider
The class skeleton looks like this:
public class MyMembershipProvider : SqlMembershipProvider { public override bool ValidateUser(string username, string password) { }
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config) { }
public override MembershipUser GetUser(string username, bool userIsOnline) { } }
Initialize is the easy but essential part - we need the connection string name for later:
private string connectionStringName;
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config) { connectionStringName = config["connectionStringName"]; base.Initialize(name, config); }
Now we can validate the user - well, the base class does that. We only do the auditing part:
public override bool ValidateUser(string username, string password) { HttpContext.Current.Trace.Write("ValidateUser:entry");
bool bSuccess = base.ValidateUser(username, password);
string connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
SqlConnection conn = new SqlConnection(connectionString); SqlCommand cmd = new SqlCommand("exec myLogUserVisit @username, @success, @IP", conn);
cmd.Parameters.AddWithValue("@username", username); if (bSuccess) cmd.Parameters.AddWithValue("@success", 1); else cmd.Parameters.AddWithValue("@success", 0);
cmd.Parameters.AddWithValue("@IP", HttpContext.Current.Request.UserHostAddress);
conn.Open(); cmd.ExecuteNonQuery(); conn.Close();
HttpContext.Current.Trace.Write("ValidateUser:exit");
return bSuccess; }
Step 4: Set it up - web.config <appSettings/> <connectionStrings> <add name="MyNWind" connectionString="Data Source=cbc05vpc\cbc05;Initial Catalog=Northwind;User=sa;Password=P@ssw0rd"/> </connectionStrings> <system.web> <membership defaultProvider="SuperDuperMSProv"> <providers> <clear/> <add name="SuperDuperMSProv" connectionStringName="MyNWind" type="MyMembershipProvider"/> </providers> </membership>
Step 5: View the auditing information - default.aspx.cs
The final "UI" looks like this:
The source code is rather simple:
protected void Page_Load(object sender, EventArgs e) { MyMembershipUser currentUser = (MyMembershipUser)Membership.GetUser();
Label1.Text = currentUser.FullName; string lcConnection = ConfigurationManager.ConnectionStrings["MyNWind"].ConnectionString;
SqlConnection conn = new SqlConnection(lcConnection);
SqlCommand cmd = new SqlCommand("select * from myLoginAuditing where username=@username", conn); cmd.Parameters.AddWithValue("@Username", currentUser.UserName);
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
GridView1.DataSource = reader; GridView1.DataBind();
reader.Close(); conn.Close(); }
Done. By the way, did you notice something? Right! Alexander never fell into the trap of SQL Injection.
ExtendingMembershipProviderDemo.zip (5.64 KB)
 |
Friday, July 08, 2005 |
I'm sitting right now in that session. The speaker is just demoing yet another example which has a SQL Injection vulnerability! The killer: a script callback that uses the params unvetted to dynamically build a SQL string. MS definitely should vet the demos for security problems.
 |
Wednesday, July 06, 2005 |
Stefan Schackow (PM ASP.NET team) just demoed this cool little application here at the chalk & talk session @ TechEd in Amsterdam. The really interesting part is how to flow authentication information such as username and roles securely to the ASP application.
 |
Sunday, June 26, 2005 |
The German .NET community's July event, the ASP.NET 2.0 Community Boot Camp aka CBC05 is now fully booked! It feels absolutely great that we ( speakers are almost exclusively MVPs) were able to organize a five day training event on ASP.NET 2.0 by the community for the community. See you in Bad Ischl in July!
 |
Saturday, June 25, 2005 |
The Ajax.NET library has been open-sourced by Michael Schwarz. You can now download the most current bits here. What I didn't see so far though is the source code for the library... nor the license.
 |
Wednesday, May 25, 2005 |
 |
Tuesday, May 24, 2005 |
Dino Esposito has posted code updates here for his book Introduction to ASP.NET 2.0. I was tech editor on this book, so I definitely recommend getting the book (and no, I don't get anything for this shameless plug).
 |
Thursday, May 12, 2005 |
 |
Wednesday, March 09, 2005 |
This is a course for Visual Studio .NET 2003. Download
 |
Thursday, March 03, 2005 |
 |
Tuesday, March 01, 2005 |
 |
Sunday, February 27, 2005 |
 |
Friday, February 25, 2005 |
This is the first half of the chat over at Channel 9. The second half will come next week. I was already looking forward to that after Robert announced it last week.
 |
Thursday, February 24, 2005 |
In the article The 80/20 Rule for Web Application Security, there is one security solution proposed to protect sensitive cookies: adding the httpOnly flag. This attribute prevents cookies from being accessed through client-side script, thus mitigating the risk of cross-site scripting.
All you have to do in ASP.NET 2.0 to take advantage of this security feature is to add the httpCookies element with the httpOnlyCookies attribute set to true to web.config: <?xml version="1.0" encoding="utf-8"?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <system.web> <httpCookies httpOnlyCookies="true"/> </system.web> </configuration>
That's it - but you are still free to override this on a per-cookie basis.
 |
Wednesday, February 23, 2005 |
A new property has been added to the TextBox control you already know: the AutoCompleteType property. What does it do? It let's you specify the field of a user's vCard to automatically populate the TextBox. Take a look at the following form:

The user must type in the name every time she is on the form. Tedious. No longer if you assign the DisplayName vCard attribute to the TextBox:

Now, if you had typed in your display name in a different form already, it will automatically pop up as a choice when filling in the form:

The screenshot already implies that this is a cross-browser feature, the generated HTML source code does indeed confirm this assumption: <input name="txtName" type="text" vcard_name="vCard.DisplayName" id="txtName" />
Yet another nice feature of ASP.NET 2.0 to look forward to.
 |
Tuesday, February 22, 2005 |
Once again working on my backlog... interested in ASP.NET 2.0? Then watch the videos on this page. Jeff Prosise talks about Web Forms, State Management, Security, Master Pages and Site Navigation, Data Access as well as Application Infrastructure.
 |
Saturday, February 12, 2005 |
CodeHTMLer is a Web application for creating nicely formatted (and colored) HTML from your source code (C#, VB.NET, et cetera). Aside from the functionality, the newsworthy bit is that it comes with (C#) source code, which is BSD-licensed as far as I can tell from the wording.
New in the Download Center: an ISO image of Exploring ASP.NET 2.0 Using Visual C# 2005 (CD1), a training course provided by AppDev. CD Contents include:
- AppDev user interface
- Video demonstrations
- Testing
- Full courseware on PDF covering the content on the CD
As stated in the title, I am currently downloading. So I can't yet tell what is all in there.
 |
Friday, January 21, 2005 |
In case you have been wondering "What is he doing?" - I have been busy preparing my three talks for the ASP konferenz and VS2005 konferenz respectively:
- ASP.NET 2.0 Master Pages and Themes
- ASP.NET 2.0 Membership and Security
- Visual Studio Team System Team Developer in-depth
 |
Monday, December 13, 2004 |
The Microsoft ASP.NET v1.1 Membership Management Component Prototype contains classes that allow a developer to more easily authenticate users, authorize users, and store per-user property data in a user profile. The authentication feature validates and stores user credentials which a developer can use to manage user authentication on a web site. The authorization feature lets you treat groups of users as a unit by assigning users to roles such as manager, sales, member, and so on. Combined with ASP.NET's built-in authorization functionality, Windows Shared Hosting developers have end-to-end support for maintaining user-to-role mappings and authorizing users based on this information. The profile feature enables you to provide users of your Web site with a custom experience. By defining and using profile properties, you can track any custom information your application requires, including user information and user preferences. Download
 |
Monday, December 06, 2004 |
 |
Friday, December 03, 2004 |
Using WSE 2.0? Get SP2. Dont't know what WSE is? Here is a quick overview from the download page:
WSE 2.0 SP2 simplifies the development and deployment of secure Web services by enabling developers and administrators to more easily apply security policies on Web services running on the .NET Framework. Using WSE, Web services communication can be signed and encrypted using Kerberos tickets, X.509 certificates, username/password credentials, and other custom binary and XML-based security tokens. In addition, an enhanced security model provides a policy-driven foundation for securing Web services across trust domains. WSE also supports the ability to establish a trust-issuing service for retrieval and validation of security tokens, as well as the ability to establish more efficient long-running secure communication via secure conversations.
 |
Thursday, December 02, 2004 |
Need a ViewState Decoder? Want to view the ASP.NET security context? Generate a machine key? Trying to understand the ASP.NET pipeline? Or looking for a password minding application? All this plus more can be found for free on this page.
 |
Tuesday, November 16, 2004 |
Brian has the details in his blog for the two changes:
- ASP.NET 2.0 Directory Naming Changes
- ASP.NET 2.0 Compilation Model Changes
 |
Saturday, October 16, 2004 |
 |
Friday, October 08, 2004 |
 |
Wednesday, October 06, 2004 |
Early Tuesday morning last week, I already had a blog entry up with exactly that title. However, I took it down because Scott Guthrie did ask to buy some time for his ASP.NET team which was already working on a fix for the zero-day exploit reported on NTBugtraq. I changed my entry to Two of the most important security mailing lists, an article containing useful advice– especially programmers are usually not subscribed to these lists, and this I consider to be bordering on irresponsible these days.
To get back to the security bug in Forms Authentication: the ASP.NET team has posted a KB article and a security alert. Turn to implementing the workaround options immediately!
An IIS best practice using URLScan for the backslash canonicalization issue found in ASP.NET was brought up independently by Stephan on our German ASP.NET mailing list last Tuesday. Too bad that we had to advise lots of people to install a tool that was readily available for years!
Bootnote: Hadn’t it been a security vulnerability for ASP.NET, I would have never even considered taking my blog entry down (the ASP.NET team is just absolutely fabulous and their support for the community rocks). I flat-out do not believe that one helps the good guys by not telling them about publicly known zero day exploits (NTBugtraq isn’t just any mailing list after all, and shooting the messenger never was a brilliant solution). This is why the German ASP.NET community knew about the sploit before 7:30AM CET on Tuesday. Even if we hadn’t found a workaround, disabling vulnerable sites would still have been a much better choice than being hacked without knowing.
 |
Thursday, September 30, 2004 |
OWASP (The Open Source Web Application Security Project) has a couple of projects online focused on ASP.NET security issues. Current projects include ANBS (ASP.NET Baseline Security), SAM'SHE (Security Analyzer for Microsoft's Shared Hosting Environments), ANSA (ASP.NET Security Analyzer) as well as the ASP.NET Security Guidelines for designing and deploying secure Web applications using ASP.NET (applicable to IIS 5 & 6).
OWASP .NET Projects Homepage
 |
Friday, September 17, 2004 |
In this episode, Brian Goldfarb shows some of the new tools enhancements that are coming with Visual Web Developer 2005 Express Edition and Visual Studio 2005. See enhancements to both design editor and code editor like validation, Intellisense improvements, source code preservation, and more. Video download
 |
Wednesday, September 08, 2004 |
The Platform Lab (Building 20) is where product teams meet customers (heck, I was there just recently, and yes, it was the ASP.NET team hosting the event). In this Channel 9 video (download), Scott Guthrie takes you on a tour of the building.

 |
Thursday, September 02, 2004 |
 |
Tuesday, August 17, 2004 |
Shanku Niyogi, ASP.NET Group Program Manager posted a blog entry on Upcoming Changes to ASP.NET 2.0 in Beta 2. Now, any further questions why I keep trying to convince people not to start production projects on a non-feature freeze Beta version?
Finally got my hands on Dino Esposito's book Introducing Microsoft ASP.NET 2.0. The term "finally" has a special meaning for me: I was the technical editor on this book, and quite a lot of work went into this book project, because writing such a book isn't done in a day, and ASP.NET 2.0 was/is a moving target. So even with the most stringent editing, there inevitably will be some "mistakes" caused by changes.
In the Acknowledgements, Dino writes "Christoph Wille, who reviewed the contents from a technical perspective, was one of the most attentive and insightful reviewers I have ever had (and I have written quite a few books)." He has a gift for words - a royal pain in the posterior would be the tagline I'd choose for myself.
 |
Tuesday, August 03, 2004 |
This month's issue of MSDN Magazine sports an article from Dino Esposito on the topic of script callbacks (read it). I consider script callbacks one of the cool features of ASP.NET 2.0, so be sure to check it out!
 |
Monday, July 26, 2004 |
Thomas (de) picked up the topic of validating multiple forms in ASP.NET 1.1 (de) - and was wondering if / how this is solved in 2.0. Great opportunity to start my series on "What's cool in 2.0". The good doctor is in!
One of the features on the (rather long) list of cool features in 2.0 is validation groups. It allows you to group certain controls - validators and controls that allow (auto-)postback - in a validation group: only the validators in the group that is posted back is actually being executed.
Let me illustrate, take a look at the following "two form page" (contrived as always):

In the old days of 1.1, when you clicked either of the two buttons, all validators would be executed, even though not all are applicable for both forms. In 2.0, all you have to do to sort out this dilemma is to set the ValidationGroup property:

Now when we run our sample application, only the validators associated with the respective "form" (validation group defined by the button) fire:

I'm sure that a lot of my fellow developers can't wait till this feature RTM's!
To wrap up, Stephen Walter wrote the article Changes to the Validation Controls in ASP.NET 2.0, which goes into more depth on the validation control changes.
 |
Tuesday, July 13, 2004 |
Just in case you missed it - the Quickstarts are online. Definitely a quick way to get started and no, it is not strictly ASP.NET 2.0 only: Windows Forms, J# and Common Tasks make an appearance too.
© Copyright 2010 Christoph Wille
newtelligence dasBlog 2.3.9074.18820  |
|