Wednesday, November 3, 2010

Displaying a temporary page while upgrading an ASP.NET website

Having used this feature before, I knew that there was a simple way to have your ASP.NET 2.0 web site close down and show a temporary (or under construction, etc) page while the website is being upgraded (or deployed, etc), but I couldn’t remember the details.

It took a few tries before I found the relevant details via Google, so I thought I’d post about it to remind me in future.

Basically, if you copy a file called app_offline.htm into the web site’s root folder then ASP.NET (version 2 onwards) will just serve that file in response to any and all new requests.

Wednesday, October 20, 2010

Windows batch files

Introduction

In general they suck. They started off weak and even though they have improved with each release of Windows this just leaves you with a backwards-compatibility problem.

On the other hand, they are built in to Windows. Using something else introduces a dependency on a third party tool. If you want to provide a simple example of how to call your program from a command line, or want to save a command and its parameters and run it by double-clicking or from a scheduled task then a batch file will do.

One big problem used to be that the current folder defaulted to the Windows folder when the batch file is executed by double-clicking it, leaving you with the problem of finding where your stuff is. Installing all your files into the system folder or putting everything in the path is generally not workable.

Here’s a simple example batch file that will set the current folder to be the folder the batch file is in, which will, presumably, also be the one your executables are in. Paste it into a text file and save it as example.bat. You can run it by double-clicking it in Windows Explorer or by typing the filename into the command prompt and pressing Enter.

You can get help for most of the commands by typing help followed by the command name at the command prompt.

Example batch file

@rem Switch echo off
@echo off

rem Fixing current folder

echo Current folder at start: %cd%

set ARG0=%0%
echo Argument 0: %ARG0%

echo Drive: %~d0%
echo Path:  %~p0%

if %~d0==\\ goto UncNotSupported

pushd %~dp0%
echo Current folder now: %cd%
popd

echo Current folder at end: %cd%

goto end

:UncNotSupported
echo UNC paths not supported - try mapping a drive with "net use"
goto end

:end
if "%1%"=="" pause

Deconstruction

By default, each statement is echoed to the output before it is executed. This can be very handy for debugging a batch file (especially as variables don’t always work the way you might expect), but makes the output harder to follow.

Starting a line with @ prevents the line from being echoed. It’s just interpreted and executed. The first line is a comment, rem being short for remark, so it doesn’t do anything. It would still be echoed to the output so the line starts with @ to prevent this.

The second line of the script uses the echo command to turn echoing off for the rest of the script. This line would also be echoed so starts with @. Once echo is off we can dispense with starting each line with @.

You might want to switch echo back on and off again for sections of a batch file when debugging because the echoed output will display the values that variables, etc, have expanded to.

The next line is a straightforward comment.

Then I use the echo command in a new way: to write something to the output for the user to read. I write out a message and the value of the current folder, which I get from the cd pseudo-variable. The % symbol is used to enclose variable names. Other commands may work with just an initial %, but I usually enclose them anyway (if possible) to be consistent. The inconsistency around variable expansion is just part of the suck of batch files.

Next I create a variable, called ARG0, with the set command, and then I output the value. Batch files can be fussy about the set command and won’t work if you try to use spaces around the =. The variable called 1 expands to the value of the first parameter passed to the batch file (if any) and 2 is the second parameter, etc. The 0 (zero) variable is automatically set to be the full path (and file name) of the batch file itself. Putting this into another variable is redundant, but demonstrates how to set a variable.

The next two lines use an extended version of the variable expansion to output the drive letter and path from %0%. See the for command for details (help for from the command line).

The next part of the suck is that the command line cannot have its current folder set to a UNC (Unified Naming Convention) path (a share on a server such as \\server\share). If you try to run this batch file from a share then it won’t work. You can map a drive letter to the share and then run it as normal.

The next line detects UNC paths, demonstrating the if command. If the batch file is running from a UNC path then I use a goto to jump to a label. While goto is generally considered to be a bad thing, the flow-of-control support in batch files is so sucky I generally avoid it and stick to using goto.

If you really, really need to have the batch file run via a UNC path then it might be possible to figure out the share’s path from %0% and then build fully-qualified paths to all files referenced from the batch file. I’ve not tried this though.

The pushd command changes the current folder to be the folder the batch file is stored in by using a combined form of the variable expansion we saw earlier. This evaluates to the drive and path, lopping off the batch file’s name. pushd will also save the previous current folder onto a stack and this can be restored via popd. This is useful because if your batch file is called from another batch file then you need to put the old current folder back before you finish or you risk breaking the calling batch file.

Any payload for a real batch file would go between the pushd and the popd. In this case I just output the new current folder to show it worked.

I use a goto to skip over any other labelled blocks, such as the one I used to handle UNC paths, and exit the batch file. Before we exit it’s nice to use pause so the user can see what we did. If we don’t pause and the batch file was launched via a double-click then it just vanishes at the end. If the batch file is called from another batch file then the pause isn’t necessary so I check the value of the first parameter passed to the batch file. If it is empty then I pause. If called from another batch file then anything can be passed as a parameter to the batch file to have the pause skipped.

Conclusion

So, what have I achieved here? Not a lot really. This batch file is an example which demonstrates some simple techniques (formatting output, getting and setting variables, conditional jumps, etc) and works-around a problem with current folders which isn’t even relevant on Windows 7 & Windows Server 2003 (at least) as they seem to change the folder automatically anyway.

Writing to files (logging, etc)

This stuff isn’t in the example above, but might also be useful.

echo blah blah > example.log

The above writes the output to a file, overwriting it if it already exists. Using >> would append it instead.

type example.log | more

The above should output the file, but instead of writing directly to the output it should be sent to the more command as input. more just sends it to the output anyway, but introduces a pause after each page so the user can read a file a page at a time. Completely obsolete, but in theory this ‘piping’ could be used to plug all sorts of little commands and batch files together. Not tried it myself. Sounds painful.

Friday, August 13, 2010

ASP.Net MVC

Here is a brief summary of the first chapter of Professional ASP.NET MVC 1.0, which is freely available to download from http://tinyurl.com/aspnetmvc. Even though it’s only the first chapter, it’s a walkthrough of a worked example and, at ~180 pages, covers a lot of ground. It’s also available for Kindle and an updated version for MVC 2.

The core of it is the model, view & controller pattern. While this isn’t a new idea, it’s still an improvement on the traditional Forms approach. The Model represents the data objects. Views are screens/pages, etc. Controllers process user requests (via URLs for example) by performing actions in the model and responding with an updated view, for example.

Applying the MVC pattern means the framework can provide built-in support for additional features, such as:

  • Routing – controls how URLs map to controllers. This makes it easy to create and maintain Search Engine Optimised (SEO or ‘Google friendly’) URLs.
  • ActionLink & RouteLink helper methods – creates URLs appropriate for the controllers. Avoids manually generating anchor tags. Can also do redirects.
  • Authentication & Authorisation – can decorate the Controllers’ action methods with role names and have the framework enforce security.

Perhaps the biggest benefit is that it’s simpler to unit test due to the greater separation of concerns – the model abstracts the database access and, if mocked, the views and controllers can be tested without a database actually being present. The final part of the chapter provides a walk through of this using dependency injection and Moq.

Early in the chapter we get an introduction to Linq To Sql, an Object Relational Mapping (ORM) tool. This can be used to quickly create an object model from SQL tables.

Some other things demonstrated include:

  • Scaffolding – quickly create basic default views (CRUD pages, etc) from templates (.aspx files).
  • Extension methods – add a method to a class without actually altering the class.
  • ViewModel classes – helper classes that expose the parts of the model needed by a specific view. Prevents exposing the entire model to every view. The ViewModel is constructed by the controller from the model.
  • Master pages & partial views – master pages allow the site’s shell to be specified once, rather than repeated on each page. Partial views are for sharing bits of views and for breaking UI things up into simpler parts.
  • Pagination – how to retrieve subsets of large result sets.
  • AJAXjQuery & JSON – demonstrates how to make a lightweight call to the website using AJAX; uses a simple jQuery text-animation effect; and sends data to a page in JSON format.

Overall, I recommend it. While many of the subjects covered will each take a further book to cover in any depth, the chapter does provide an excellent overview.

Saturday, July 31, 2010

Windows Live Writer

This blog post was written with Windows Live Writer, which is freely available from Microsoft. Just doing a quick test post with it to see how it plays with my Google Blogger blog.

Updated: Seems to work ok.

Thursday, July 29, 2010

Dia - free diagram drawing utility (like Visio)

Dia is a diagramming tool, a bit like Microsoft Visio, but free. You create a diagram out of shapes and lines and if you move shapes around it automatically keeps all the lines pointing to the right shapes.

In the following diagram I've just used the basic box shape, basic line connector and some text objects (I'm using version 0.97.1). Dia comes with a bunch of other pre-created shapes for drawing UML diagrams, network diagrams, etc.


The text objects are also connected to the shapes and also move around automatically. It took me a while to figure this out as dragging a text object onto a shape's connection point didn't appear to 'latch-on' as I expected it to, but this is just a wrinkle of the UI - let go and the point should change from green to red to show it's bound to a shape. The text objects will also bind to connection points on lines and you can bind both a text object and a line-end to the same connection point if you want.

A little time-saver: if you click on a connection point when adding a line or text object, then the line or text object will be created and bound to that point.

I've bound the line-ends to the connection points in the centre of the boxes (not shown). The lines automatically move around the box edges so you don't have to alter the connection point bindings if you move shapes around.

I tried putting the boxes and lines on different layers. While this worked, I got errors when I reloaded the diagram and all the objects were all disconnected. I've moved them all back to a single layer for now. Hopefully this will be addressed in a future release.

Dia can also auto-scale the diagram to fit a page. Use File > Page Setup and use Fit To 1 by 1, for example. Check the paper size and orientation too. Note that if you want to export the diagram to an image format later you might need to swap back to specifying a scaling otherwise the image can come out a little 'blocky'.

Friday, July 23, 2010

SequoiaView - why is my hard disk full?

SequoiaView is a free tool that shows you how your disk space is being used and is very useful when trying to identify what is taking up all your disk space. By default it shows all the files as grey boxes, but it can also be configured to use different colours for different file types.