Posts for category 'Programming'

.Net Configuration Section Documentation Generator

Today I'm releasing another small tool that I created for personal use that I believe others might find of use. The tool is the .Net Configuration Section Documentation Generator (more proof that I should not be put in charge of naming things), which does what it says on the tin: it generates documentation for configuration sections defined using .Net's ConfigurationSection class.

Basically, it can generate an XSD schema from a ConfigurationSection, to which you can then add annotations to document the elements and attributes of the section, and then generate an HTML documentation file from that schema. The tool can be used with Microsoft .Net and Mono.

As an example, check out the schema for the documentation generator's own configuration section as generated by the documentation generator, and with added annotations. And finally, the documentation file generated from the annotated schema. This is only a very trivial configuration section, but it gives you an idea of what the output of the documentation generator looks like.

More information and downloads here.

Categories: Programming, Software
Posted on: 2013-06-08 10:42 UTC. Show comments (3)

Creating a route for a .asmx Web Service with ASP.NET routing

While working on the update to my site (which is now completely finished), I came across a minor problem: I had an old ASP.NET Web Service (you know, the .asmx type, predating even WCF) that I needed to preserve at the same URL for compatibility purposes.

However, that URL was inside a folder on the old site. And in the new ASP.NET MVC site, that folder didn't exist anymore; instead, requests for that path were handled by an MVC Controller. This meant that it was not possible to leave the .asmx file at its original location, because an existing physical directory pre-empts the MVC route for the controller, so it would render all the other pages with the same base URL unviewable.

I figured I'd be able to use RouteCollection.MapPageRoute to redirect the old URL to the .asmx file's new location, but it turned out that this function only works for pages (.aspx files), as it requires that the HTTP handler for the route's target derives from System.Web.Page. Searching the web wasn't able to find a solution for this, but some investigation into the inner workings of ASP.NET routing let me devise my own solution, which I thought I'd share here.

The trick, it turns out, is to create a custom IRouteHandler, one that is able to return the correct IHttpHandler for web services. This turned out to be fairly simple:

using System;
using System.Web;
using System.Web.Routing;
using System.Web.Services.Protocols;

public class ServiceRouteHandler : IRouteHandler
{
    private readonly string _virtualPath;
    private readonly WebServiceHandlerFactory _handlerFactory = new WebServiceHandlerFactory();

    public ServiceRouteHandler(string virtualPath)
    {
        if( virtualPath == null )
            throw new ArgumentNullException("virtualPath");
        if( !virtualPath.StartsWith("~/") )
            throw new ArgumentException("Virtual path must start with ~/", "virtualPath");
        _virtualPath = virtualPath;
    }

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        // Note: can't pass requestContext.HttpContext as the first parameter because that's
        // type HttpContextBase, while GetHandler wants HttpContext.
        return _handlerFactory.GetHandler(HttpContext.Current, requestContext.HttpContext.Request.HttpMethod, _virtualPath, requestContext.HttpContext.Server.MapPath(_virtualPath));
    }
}

This route handler can then be used to add a route for a .asmx web service:

routes.Add("RouteName", new Route("path/to/your/service", new RouteValueDictionary() { { "controller", null }, { "action", null } }, new ServiceRouteHandler("~/actualservice.asmx")));

One important thing to note is the RouteValueDictionary values I'm passing to the route. If you don't add values for "controller" and "action" to the dictionary, the Html.ActionLink helper method will match this route for any controller or action, leading to completely incorrect URLs if this is the first matching route. Since you probably want to have this route before the MVC default route (which was the case for me), that would be a problem. Setting the values in the route value dictionary resolves this issue.

Of course, you can create your own extension method to make this easier:

public static Route MapServiceRoute(this RouteCollection routes, string routeName, string url, string virtualPath)
{
    if( routes == null )
        throw new ArgumentNullException("routes");
    Route route = new Route(url, new RouteValueDictionary() { { "controller", null }, { "action", null } }, new ServiceRouteHandler(virtualPath));
    routes.Add(routeName, route);
    return route;
}

Which means you can now simply use this:

routes.MapServiceRoute("RouteName", "path/to/your/service", "~/actualservice.asmx");

And voilà, I was now able to preserve the URL to my legacy web service without needing to have a physical file matching that URL. If you're faced with a similar situation, I hope this helps you.

Categories: Programming
Posted on: 2013-05-30 15:56 UTC. Show comments (689)

Welcome to the new Ookii.org

As you can see, Ookii.org has gotten a revamp. Now you may wonder, why make such a radical update to a site when the content doesn't change that often? The main reason is that I wanted to get my hands dirty with some modern web technology.

While web development has never been particularly important to me, it was something I knew how to do and I kept somewhat up-to-date with. This dates back to making the site for my high school (at the time in Frontpage). However, as I'd been busy with my Ph.D. in Japan, I had very little time to keep up to date with stuff I didn't have any need to use in my research. Now that I've finished and haven't started my new job yet, it was the ideal time to brush up a little.

Back when I started this site, I wrote it in ASP.NET 2.0. I hand-rolled an AJAX library, because jQuery was years from being invented and actually AJAX support in websites wasn't all that common yet. The AJAX parts of the site used web services that returned data in XML, because no one had thought to start using JSON yet either. "Mobile browsers" at the time meant IE for Windows Mobile, which didn't support script at all and was barely on par with IE6 on the desktop otherwise. And speaking of IE6, supporting that was still very much a priority at the time.

But things have changed, and the goal was to re-familiarize myself with the state of the art. So this site is written in ASP.NET MVC 4, using the Entity Framework for data access. On the client, it uses HTML5 and CSS3, with scripts utilizing jQuery and a few related libraries. The site now has a responsive layout thanks to Zurb Foundation (try it: resize your browser window and watch the layout change), which has the side-effect of making it much more friendly for mobile devices. I've also used Knockout.

I have to say I was surprised at how much web programming has changed. ASP.NET MVC is light-years beyond the old web forms. Not only are the frameworks much better and the HTML/CSS much cleaner (at least, as long as you only target modern browsers), the tooling (in the form of Visual Studio 2012 in my case) also has improved tremendously.

Besides just redesigning the layout, I've also made a new front page that de-emphasizes the blog a little (since I don't update it that often), and instead provides a few more useful links as well as news about my Let's Plays from the associated Twitter account.

Note that not everything uses the new layout. Currently, only the blog has been updated. I intend to move other sections of the site to the new layout over time.

Let me know what you think, or if you find something that's broken.

Categories: Programming, Site news
Posted on: 2013-05-07 19:50 UTC. Show comments (10)

Ookii.CommandLine 2.2

Yes, I realise this blog is all but dead. However, I will soon finally complete my Ph.D. at the University of Tokyo (so, yay me!), and as a result I can now finally release a few things that had been put on hold while I was writing my Ph.D. thesis. In addition, I will probably release a few projects related to my research that may hopefully be of interest to some people.

First up is a small update to Ookii.CommandLine. This update adds command line argument aliases, some updates for usage help generation, and code snippets to help with creating argument classes.

In addition, I used NuGet to create a symbols package and published it on SymbolSource, which you should apparently be able to use as a symbol server in Visual Studio without manually downloading the symbols.

Get the release from CodePlex or using NuGet.

Categories: Programming, Software
Posted on: 2013-02-06 12:11 UTC. Show comments (2)

FormatC 2.0 (syntax highlighting) now available

With the release of .Net 4.0 I have updated the FormatC syntax highlighter (used for all code samples on ookii.org) to support new keywords introduced in Visual Basic 10.0 and C# 4.0.

That's not the only update, however. FormatC 2.0 also has the ability to escape contextual keywords (previously, it would treat them as keywords regardless of the context), type name highlighting support for Visual Basic and improved XML literal support in Visual Basic.

PowerShell support is also improved; FormatC will try to use the parser included with PowerShell 2.0 to parse the code. Unfortunately, this web server does not have PowerShell 2.0 installed, so the online version of the highlighter will still use regular expressions to highlight PowerShell code.

If you have any feedback about FormatC, please leave it as a comment on this blog post.

Sample C# code highlighted using FormatC:

public static int SumAuthorPrices(IEnumerable<Book> books, string author)
{
    if( books == null )
        throw new ArgumentNullException("books");

    return (from b in books
            where b.Author == author
            select b.Price).Sum();
}

Sample Visual Basic code highlighted using FormatC:

Public Shared Function ConvertToXml(ByVal books As IEnumerable(Of Book)) As XDocument
    If books Is Nothing Then
        Throw New ArgumentNullException("books")
    End If

    Return <?xml version="1.0"?>
           <Books>
               <%= From b In Books
                   Select <Book Author=<%= b.Author %> Price=<%= b.Price %>>
                              <%= b.Title %>
                          </Book> %>
           </Books>
End Function

Sample XML code highlighted using FormatC:

<?xml version="1.0"?>
<Books>
  <Book Author="Peter F. Hamilton" Price="18.99">
    The Evolutionary Void
  </Book>
</Books>

Sample T-SQL code highlighted using FormatC:

SELECT title, author, publisherName FROM Books b
  INNER JOIN Publisher p
  ON b.publisherId = p.id
WHERE b.price >= 10

Sample PowerShell code highlighted using FormatC (this used the parser-based method, not regular expressions):

foreach ($file in Get-ChildItem)
{
    if ($file.Length -gt 100kb) 
    {
        Write-Host -ForegroundColor Green $file
        Write-Host $file.Length
        Write-Host $file.LastAccessTime
    }
}

Categories: Programming, Software
Posted on: 2010-08-07 05:23 UTC. Show comments (1)

Latest posts

Categories

Archive

Syndication

RSS Subscribe

;