Visual Studio 2005 comes with a built-in webserver, called Cassini. While it works fine for most things, it has a few limitations (which are reasonable for a built-in webserver). One of the limitations is that it only serves local requests. Another limitation is that it doesn't use http.sys, which means it can't share a port with for example IIS.

I decided to put together a little webserver using HttpListener, which is a managed interface for http.sys. This webserver should be able to do everything that Cassini can do and more. You can still limit requests to for example localhost by specifying a different host ('prefix') when starting the server. Hopefully this turns out to be useful for someone playing around with Indigo/WCF, or for someone who wants to let others see a local webapp.

License:
This project is released under Ms-PL. Please contact me directly for questions or exceptions.

Downloads:

Most recent updates:

  • Fixed: Removed a hardcoded path in the GUI project file Program.cs
  • Fixed: Virtual path is now guaranteed to include a trailing slash (which other bits of code rely on)
  • Fixed: GetTranslatedPath may return an invalid path in certain scenarios.

Thanks to Nicko (see comments) for both pointing out these bugs and providing fixes.

This is a relatively advanced security application block which may be used in both windows and web applications. Please read my post for more information.

Samples:

License:
This project is released under Ms-PL. Please contact me directly for questions or exceptions.

Downloads:

The following controls are part of a custom web control library for ASP.NET, Wilco.Web. The source code is available for download. The download includes a set of custom controls, aswell as some helper classes used by those controls (such as the ViewStateHelper).

Demos:

License:
This project is released under Ms-PL. Please contact me directly for questions or exceptions.

Downloads:

Updates:

  • 30/aug/07: Added HtmlFormEx.RenderFieldsToBottomOfPage. Can be a useful optimization for search engines that only index the first n bytes of a page.

Most URL rewriters out there only let you rewrite requested URL's to internal URL's. In practice, you often see people create/generate friendly URL's and then create mappings for those friendly URL's to internal URL's. Whenever you would decide to change your friendly URL's, you have a problem. You have to change the mappings AND the created/generated URL's.

To overcome this problem, I put together a 2-way URL rewriter. It lets you define mappings from a friendly url to the real url, and vice versa. The default web config rule provider lets you define the mappings as follows:

XML:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 

<configuration>
  <configSections>
   <section name="rewriter" type="Wilco.Configuration.ProviderSectionHandler, Wilco.Configuration" />
  </configSections>

  <rewriter>
    <provider type="Wilco.Web.RewriteEngine.Providers.WebConfigRuleProvider, Wilco.Web.RewriteEngine">
      <rules>
        <rule>
          <!-- /blah.aspx - /default.aspx -->
          <inbound pattern="~/blah.aspx" replacement="~/default.aspx" />
          <outbound pattern="~/default.aspx" replacement="~/blah.aspx" />
        </rule>
        <rule>
          <!-- /news/123 - /news.aspx?newsid=123 -->
          <inbound pattern="~/news/(\d+)$" replacement="~/news.aspx?newsid=$1" />
          <outbound pattern="~/news.aspx\?newsid=(\d+)$" replacement="~/news/$1" />
        </rule>
      </rules>
    </provider>
  </rewriter>

  <httpModules>
    <add name="Rewriter" type="Wilco.Web.RewriteEngine.Rewriter, Wilco.Web.RewriteEngine" />
  </httpModules>
</configuration>

The rewriter comes with an HttpModule which takes care incoming URL's. Internally it relies on the helper method 'string UrlUtility.ConvertToRealUrl(string friendlyUrl)'. This helper class also contains a method 'string UrlUtility.ConvertToFriendlyUrl(string realUrl)', which does the obvious.

Custom providers can be implemented, by either inheriting from the web config rule provider or implementing IRuleProvider. You can download the binaries and source for free.

License:
This project is released under Ms-PL. Please contact me directly for questions or exceptions.

Update:
Please have a look at my HtmlFormEx implementation which should be used together with this component to solve an issue with postbacks.

About a year ago or so I wanted to add the ability to syndicate my news page. Therefore I wrote this small library which did the trick for me.

The Provider:
If you want to provide an RSS feed, you should use the Wilco.Web.Rss.RssProvider servercontrol. After dropping it on an empty page, you only need to build a DataTable data source and set a few properties. This would result in something like:

C#:
1 
2 
3 
4 
5 
6 
7 
8 
9 

..
DataTable source = this.GetDataSource();
this.provider.Feed = new RssFeed();
this.provider.Feed.Data = source;
this.provider.Feed.Elements.Add("title", "My RSS Feed!");
this.provider.Feed.Elements.Add("link", "http://www.domain.com/");
this.provider.Feed.Columns.Add(new Column("title", "NewsItemTitle"));
this.provider.Feed.Columns.Add(new Column("link", "NewsID", "http://www.domain.com/entry.aspx?id={0}"));
..

The Reader:
The RSS reader's usage should be similar to standard ASP.NET controls such as a Repeater and DataList. All you need to do is set the Source and call DataBind(). A default template will be used if no template is defined. If you do want to define a custom template, you can do so just like you would with a Repeater:

ASP.NET:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 

<script language="C#" runat="server">
void Page_Load(object sender, EventArgs e)
{
    reader.Source = "http://www.domain.com/somefeed.rss";
    reader.DataBind();
}
</script>

<wilco:RssReader ID="reader" Runat="server">
    <ItemTemplate>Title: <%# ((DataRowView)Container.DataItem)["title"]) %>.<br /></ItemTemplate>
</wilco:RssReader>

License:
This project is released under Ms-PL. Please contact me directly for questions or exceptions.

Downloads:

Requirements:

Initially I wanted to be able to easily highlight syntax on my website while writing things. I took a look at Microsoft's QuickStart highlighter, and even based my first implementation on it. But I was quite disappointed about the endresult: it didn't really give me what I was looking for.

So I started with my own implementation from scratch. My requirements were:

  • Extensibility - it should be easy to extend existing highlighters.
  • Reusability - it should be easy to reuse parts of the highlighters.
  • Configuration support - highlighters must be able to be build from a configuration file and/or store their configuration.
  • Separated functionality - a highlighter shouldn't for example parse the syntax in HTML.
  • Easy to use - the client of the component should be able to parse code for a specific language with just a few lines of code.
  • ASP.NET support - it should be possible to easily highlight code on a page, either in-line or code-only.

I started modelling the things I had in mind and finally came up with the following model:

The Class Diagram of the Highlighter

In this model you can see that an highlighter works like a facade: the client doesn't have to worry about setting up the right scanners the right way. It's all done in each highlighter. This means that the requirement 'easy to use' is met in this model.
Each highlighter contains a set of scanners, which together basically form an highlighter. Scanners can be written once and be used within all the highlighters. Because I've implemented a chain of responsibility for the relationship between the scanners, highlighters or clients of highlighters can easily modify the chain. All this meets the requirements 'reusability', 'separated functionality' and 'extensibility'.
Since highlighters don't actually parse the syntax, but parser implementations do, requirement 'separated functionality' is met again. At any time someone could add a parser and still use all the highlighters.

After building this model, I started with the implementation of the design. When the core was done, I started implementing a set of common scanners, such as an XmlScanner, and finally implemented some highlighters, such as a CSharpHighlighter for highlighting C# code, and an HTML parser.

The requirement 'ASP.NET support' was not met yet at this point. So I made a ASP.NET server control which basically acted as a Label server control, except that it had 3 modes: all text, text and in-line source, and all source.

To meet the last requirement I extended the interface for scanners. With this extended interface, scanners could both load and save their configuration. By providing an implementation configuration manager which makes use of this extension, the last requirement was met too.

License:
This project is released under Ms-PL. Please contact me directly for questions or exceptions.

Downloads:

Recent updates (May 22nd, 07):

  • Fixed: CSS failed to highlight when plain text was used. Credits go to Andrew Powell for finding and fixing this.
  • Updated: Incorporated changes provided by Atif Aziz to take away a major performance bottleneck.
  • Fixed: XML attributes which contain double quotes and single quotes are now properly processed.

Winamp lets you add several kind of plugins, such as general purpose plugins. Since it doesn't know anything about .NET, I decided to write a proxy using C++/CLI (initially I did this using Managed C++). The result is a proxy DLL that will sit between a managed plugin (written in C#/VB.NET/etc) and Winamp. The proxy will simply delegate all calls from Winamp to the managed plugin.

To demonstrate the proxy, I've written a WinampAlarm plugin (source/binary included in the download). It's a basic plugin written in C# and is loaded by the proxy (which is possible due to a strict naming convention of the DLL's).

Usage:
Download the zip and move the gen_*.dll's to your Winamp's plugin directory.

Downloads:

This new application updater is a new application updater component which is customizable and supports both WebDAV and BITS (Background Intelligent Transfer Service). BITS allows you to let the application download updates in the background, which means users would practically not notice anything, since BITS will use unused bandwidth.

Usage:
Add a reference to Updater.zip and implement the IAgent interface. Your IAgent implementation will be used for getting available updates and such.
When you've done that, you write your own download implementation in case you don't want to use WebDAV or BITS to download updates.
The next thing you got to do is initialize a new Updater, add eventhandlers, and that's basically all you got to do.
If you want to check for updates, you call the Refresh method on the Updater instance, when you've detected an update you call the Download method, and when you're done with updating and want to restart the application, you use the ApplyUpdate method.

Status:
Early release, yet it should work fine.

Downloads:

Requirements: