Monday, December 28, 2009

Secure file system access for Windows 2008 Servers

With VPS technology becoming main stream quite a few companies are switching from shared hosting solutions to (cheap) VPS server solutions, mostly Windows based.

Security
As a web developer I need secure access to these systems. FTP is about as insecure as an unencrypted USB stick left behind in public transport. FTP is not an option.

WebDAV
I’ve given WebDAV (over SSL) a try. It works but I’m not quite happy with it. WebDAV on IIS is subject to the same rules as all other IIS applications. Meaning that it won’t allow me to update the Views folder of an MVC application because there is a web.config there that won’t give me access to that folder.
The alternative would be to install Apache for WebDAV. I’ve configured this for a customer that uses WebDAV to access shared subversion repositories. Once this is up and running it is very solid.
Installing apache however just to get secure filesystem access seems like overkill to me.
The nice thing about WebDAV is that Windows can connect to a WebDAV server directly and allows me to drag&drop files directly in explorer.

SSH
Ideally, I’d like to use SSH which I also use to access Unix based servers. I’ve looked into this a couple of years ago and found only half-baked or very expansive solutions. Recently I’ve come across freeSSHd.

It’s a near perfect solution. The only issue is that the configuration tool tries to interact with the service which is not allowed by default on Windows 2008. The work around is to stop the service, do the configuration and restart the service.

To connect to the SSH server I use WinSCP which allows me to drag & drop files onto the server.

FreeSSH installation on Windows 2008

  • Download and run the installer
  • During installation, make sure you select freeSSH to run as a service
  • Open up the computer management console and stop the freeSSH service.
  • Open the freeSSH admin console through the start menu. After starting it adds an icon to the system tray. Click that to open up the console.
  • On the Authentication tab:
    - Require password login
    - I don’t use public key login so disable public key
  • On the SFTP tab:
    Set the base folder to your web root
  • On the Users tab:
    Add users. I prefer to use Windows accounts and grant only SFTP access.
  • On the Host restrictions tab:
    Enable only administrative IP’s but you really should have a firewall policy that takes care of this.
  • On the Logging tab:
    Enable logging
  • Finally, make sure your firewall allows access to the SSH port (22 by default). As mentioned earlier it’s best to only allow access to this port for your own IP addresses.

Tuesday, December 22, 2009

Git tips : Zipping all changed files

I’ve been using git (and msysgit on my dev system) for the most part of this year. So far it’s worked great, allowing me to work on multiple branches and on multiple locations. The command-line stuff is a bit annoying though. I just can’t be bothered to remember all those pesky commands and options so I’m just going to blog about all the powerful tricks I come across.

Tip 1: Zipping all changed files
To export changes between commits in Git the following command is very handy:

git diff -–name-only commit1 commit2 | zip ../Changes.zip –@

Commit1 and commit2 can be anything like a branch name, a commit id or a tag.

Using UnxTools or Cygwin this will even work on windows.

For more info check StackOverflow or this post, which gave me the original idea.

Update : Be careful when zipping up changes like this if you have uncommitted or staged changes in your working directory because this will zip the files as they are on your disk.

Sunday, December 20, 2009

Castle: PerWebRequestLifeStyle revisited

In my previous post I talked about a problem using Castle project’s Inversion of Control container (MicroKernel and/or Windsor) during application initialization.

Today I’ve finally had a chance to dive into this subject and see if I can come up with a solution.

A workaround
Testing has shown that moving all initialization to the Application’s Init method seems to resolve this issue at runtime. I’ve tried this on my development system and on an Windows 2008/IIS7 server.

UPDATE: This workaround may cause problems because the HttpApplication.Init method is invoked when ever a new application instance is created. 
Since there can be more than one instance of the HttpApplication within an AppDomain the Init method may be invoked more than once and from multiple threads concurrently causing all kinds of nasty problems.

In contrast Application_Start is invoked once for the entire lifetime of the AppDomain in which the application runs so that is the place to do application configuration without worrying about multi-threading issues.

Components using PerWebRequestLifeStyle (PWR for short) will never work from Application_Start because at that point in the ASP.NET application lifecycle modules are not initialized yet. I’ve tried to figure out a way to make the module used by PWR work, but as far as I can tell there isn’t any. Not without breaking compatibility with Medium-trust anyway.

Note that it’s perfectly ok to create the container and register services with it from Application_Start, just don’t try and resolve any components that use the PWR life style.

Also note that this is no solution for testing an application outside of ASP.NET. For that the hybrid solution I’ve described in my previous post is still a valid solution.

Sunday, July 5, 2009

Castle: PerWebRequestLifeStyle won’t work from Application_Start

Update: Please read the follow up post on this topic.

I’m using the Castle project to implement dependency injection and inversion of control in my web applications.
Castle supports creating objects on a per-request basis which is a big help in keeping the number of objects created per request to a minimum.

I ran into a problem with this however. The PerWebRequestLifeStyle is implemented using an HttpModule to make sure objects are evicted at the end of a request. This works well except when using Castle from the Application_Start method (or the Init method for that matter).

The Application_Start method is invoked before any modules are initialized for the application and therefore any objects registered with Castle to use the PerWebRequestLifestyle cannot be used in Application_Start.

The problem manifests itself by reporting the module is probably not configured:

Looks like you forgot to register the http module Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule
Add '<add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.MicroKernel" />' to the <httpModules> section on your web.config.

Similar problems occur when performing tests outside the web environment because, well, there is no web request obviously.

Workaround
I’ve implemented a workaround by customizing the implementation of the lifestyle manager. This work-around falls back to the TransientLifeStyleManager in case the web context is not available. T
his enables both testing and application startup to use objects managed per web request.

[Serializable] 
public class PerWebRequestLifestyleManager : Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleManager 
{ 
  public PerWebRequestLifestyleManager() 
  { 
    _fallback = new TransientLifestyleManager(); 
  }

  public override object Resolve( CreationContext context ) 
  { 
    HttpContext current = HttpContext.Current;
    if ( null == current || current.ApplicationInstance == null )    
    {
      // fall back to transient behaviour if not in web context 
      return _fallback.Resolve( context ); 
    } 
    else 
    { 
      return base.Resolve( context ); 
    } 
  }

  public override void Dispose() 
  { 
    _fallback.Dispose(); 
    base.Dispose(); 
  }   
  
  public override void Init( IComponentActivator componentActivator, IKernel kernel, Castle.Core.ComponentModel model ) 
  { 
    base.Init( componentActivator, kernel, model ); 
    _fallback.Init( componentActivator, kernel, model ); 
  }   
  
  private TransientLifestyleManager _fallback; 
}

To make sure Castle uses this custom implementation I’m using a custom AttributeFacility:

internal class AttributeFacility : AbstractFacility
{
   protected override void Init()
   {
      Kernel.ComponentModelCreated += kernel_ComponentModelCreated;
   }

   void kernel_ComponentModelCreated( ComponentModel model )
   {
      var attributes = model.Implementation.GetCustomAttributes( typeof( Castle.Core.LifestyleAttribute ), false );
      if ( attributes.Length > 0 )
      {
         var attr = attributes[ 0 ] as LifestyleAttribute;
         if ( null != attr )
         {
            switch ( attr.Lifestyle )
            {
               case LifestyleType.PerWebRequest:
                  model.CustomLifestyle = typeof( Alanta.Services.PerWebRequestLifestyleManager );
                  model.LifestyleType = LifestyleType.Custom;
                  break;
               default:
                  break;
            }
         }
      }
   }    
}

I usually hook up the facility from code, like this:

var container = new WindsorContainer();
container.AddFacility<AttributeFacility>();

Update : this solution does not work on IIS7 in integrated pipeline mode. In this mode both HttpContext.Current and HttpContext.Current.ApplicationInstance are set so the detection method in the code above does not work.
I haven’t found a clean solution for this yet; I’ve had to resort to setting a flag in Application_Start that controls the behavior of the PerWebRequestLifestyleManager. Check out the demo code to see how this works.

Update : There is a discussion on this subject at the Castle Project Users group.

Update : Download the source code for this solution. The zip contains an ASP.NET MVC 1 demo application (VS 2008). The code in this

Tuesday, June 9, 2009

MVC best practices : Don’t use strings!

I’ve blogged before about why I think it’s a bad idea to use strings to refer to controllers (and routes and views etc.) in ASP.NET MVC .

Seems I’m not the only one who is uncomfortable with this.

Check Kazi Manzur Rashid's Blog for a good list of MVC best practices. First item in the list: Avoid passing the controller, action or route name as string. My point exactly!

More MVC best practices and links to other posts on Maarten Balliauw’s blog.

Friday, May 1, 2009

Alanta.Mvc : Multiple partial views without .aspx files

In my previous post I've discussed some additions to ASP.NET MVC that I've been using for some time now. I created these additions to enable me to use MVC on existing projects.

What's wrong with MVC? 
The best practices and patterns used by MVC are good but they come at a price. I feel that MVC is not flexible enough to fit in with my preferred way of building sites. Specifically:
  1. The default view engine requires files to be in predefined places, making it difficult to migrate existing ASP.NET sites to MVC without rebuilding the whole application.
  2. The default view engine uses hierarchical view composition. That's nice but not flexible enough; I want the controller to decide what view(s) to render and I want to be able to use multiple partial views on one page.
  3. MVC uses very loose binding. I prefer strong typed binding.

I've addressed the third point in an earlier post, so I won't go into that here.

The first point, about the folder layout of MVC projects, is a matter of taste. I have my reasons for not wanting to conform to the default layout. Mostly because I don't want to rebuild an application just to be able to use MVC for some new functions I'm adding. In addition to this, I find that MVC is very much centered on physical files to represent views.
In many cases I'll build a view from controls already available or by generating HTML in a helper method. Using files (aspx or ascx) to hook all this up adds a layer of complexity I don't need and certainly don't want to maintain. It would be much easier to let the controller handle this.
This brings me to the second reason from the list above. I want the controller to be able to dictate the views that need to be rendered, I do not want to delegate this to an aspx for every conceivable view.

Pros and Cons
In my previous post I've introduced a technique that solves both the first and second issue. In combination with the strong typed routing solution described in another blog post this yields a very usable variation of MVC. In short, the solution I'm offering here has the following benefits:

  • Compose views using master pages, controls and view controls (no .aspx required).
  • Load (partial) views by type (custom controls) or virtual path (user controls).
  • No strict requirements on site structure.
  • Strong-typed routing for controllers.
  • Use MVC with any ASP.NET 3.5 website.

As always, there are some downsides as well:

  • Not using an .aspx file for a view means no visual designer support for views.
  • Most of the nice Visual Studio productivity features for MVC no longer work.

Open source on GitHub
I've made the sources available through GitHub under a BSD license. I will provide best-effort support through GitHub's issue tracking. The sources include a sample website, so check it out if you're interested.
Version 1.0.0.0 is an exact copy of production code I've been using for a couple of months now so it should be stable.

Download

Sunday, February 1, 2009

Mixing webforms with MVC

MVC offers a lot of nice features but switching from regular ASP.NET webforms to MVC on exisiting projects is not easy. Out of the box, MVC is very rigid about where you place your views (.aspx). There is little support for user controls and no support at all for custom controls. This makes mixing webforms with MVC next to impossible without breaking existing functionality.

With a couple of additions to MVC though you're pretty much free to do what you want. The functionality introduced in this post enables mixing of MVC and WebForms pages. You can reuse exisiting controls, both user controls and custom controls. You can even go as far as rendering pages from just a master page and controls.

This post will show you how to compose pages from controls using the same mechanisms ASP.NET uses when rendering regular pages from .aspx files. First we'll look at the way master pages and regular .aspx pages interact and then I'll show you how to uses this interaction to do the same from an MVC controller. For some background information the internals of pages you may also want to check an earlier post on the subject.

Master pages in a nutshell
Master pages in ASP.NET use content placeholders to indicate where the page may be customized. Normally, each page (.aspx) declares content within one or more content controls. At runtime (or when precompiling) ASP.NET will generate code that registers the contents with each template container. When the page is being processed during a web request, it instantiates the contents of each of the content controls in the templates available from the master page. The key method is in the Page.AddContentTemplate( string name, ITemplate template ) method. In pages compiled from an .aspx file this method will be invoked while building the page control structure. This is done from an override of the  Page.FrameworkInitialize method, containing most of the generated code for the page. We can use that to hook up whatever content we want to render in a master page.

Implementation
The code below shows a ViewPage that supports this mechanism:

class TemplateViewPage : System.Web.Mvc.ViewPage
{
  protected override void FrameworkInitialize()
  {
    base.FrameworkInitialize();
    foreach ( var template in Templates )
    {
      AddContentTemplate( template.Key, template.Value );
    }
  }

  public Dictionary<string, Template> Templates
  {
    get{ return _templates; }
  }

  Dictionary<string, Template> _templates = new Dictionary<string, Template>();
}
This class enables us to setup a template for each content placeholder in a master page. The Template class is a straight up implementation of the ITemplate interface that supports multiple controls to be added as either a virtual path or a control instance.
class Template : ITemplate
{
  public void AddControl( string virtualPath )
  {
    if ( string.IsNullOrEmpty( virtualPath ) )
      throw new ArgumentNullException( "virtualPath" );

    if ( virtualPath[ 0 ] != '~' && virtualPath[ 0 ] != '/' )
    {
      _items.Add( new TemplateItem { _virtualPath = string.Format( "~/{0}", virtualPath ) } );
    }
    else
    {
      _items.Add( new TemplateItem { _virtualPath = virtualPath } );
    }
  }

  public void AddControl( Control controlInstance )
  {
    if ( null == controlInstance )
      throw new ArgumentNullException( "controlInstance" );

    _items.Add( new TemplateItem { _control = controlInstance } );
  }

  void ITemplate.InstantiateIn( Control container )
  {
    foreach ( var item in _items )
    {
      var control = item._control;
      if ( null == control )
      {
        control = System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath( item._virtualPath, typeof( Control ) ) as Control;
      }

      container.Controls.Add( control );
      }
  }

  List<TemplateItem> _items = new List<TemplateItem>();
      

  private class TemplateItem
  {
    internal Control _control;
    internal string _virtualPath;   
  }
}
With these classes we have the plumming setup to render a page using a master page and inject any control we want into that. Next, this needs to be hooked up to MVC. The way to do this is create a custom ActionResult.
public class TemplateResult : ActionResult, IView
{
  public string Theme
  {
    get { return _page.Theme; }
    set { _page.Theme = value; }
  }

  public string MasterPageFile
  {
    get { return _page.MasterPageFile; }
    set
    {
      if ( string.IsNullOrEmpty( value ) )
         throw new ArgumentNullException( "value" );
      _page.MasterPageFile = value;
    }
  }

  public void AddControl( string templateName, string virtualPath )
  {
    if ( string.IsNullOrEmpty( templateName ) )
      throw new ArgumentNullException( "templateName" );

    if ( string.IsNullOrEmpty( virtualPath ) )
      throw new ArgumentNullException( "virtualPath" );

    Template template;
    if ( !_page.Templates.TryGetValue( templateName, out template ) )
    {
      template = new Template();
      _page.Templates.Add( templateName, template );
    }
    template.AddControl( virtualPath );
  }

  public void AddControl( string templateName, Control controlInstance )
  {
    if ( string.IsNullOrEmpty( templateName ) )
      throw new ArgumentNullException( "templateName" );

    if ( null == controlInstance )
      throw new ArgumentNullException( "controlInstance" );

    Template template;
    if ( !_page.Templates.TryGetValue( templateName, out template ) )
    {
      template = new Template();
      _page.Templates.Add( templateName, template );
    }
    template.AddControl( controlInstance );
  }

  public override void ExecuteResult( ControllerContext context )
  {
    if ( string.IsNullOrEmpty( MasterPageFile ) )
      throw new InvalidOperationException( 
        "MasterPageFile must not be null or empty." );

    var viewContext = new ViewContext( context, this, 
      context.Controller.ViewData, 
      context.Controller.TempData );
    
    Render( viewContext, context.HttpContext.Response.Output );
  }

  public void Render( ViewContext viewContext, System.IO.TextWriter writer )
  {
    _page.ViewData = viewContext.ViewData;
    _page.AppRelativeTemplateSourceDirectory = "~/";
    _page.AppRelativeVirtualPath = "~/";
    _page.RenderView( viewContext );
  }

  TemplateViewPage _page = new TemplateViewPage();
}
This class provides a controller with the means to create a view and execute it. For a simple HelloWorld example the controller would look like this:
public class HelloWorldController : Controller
{
  public void Default()
  {
    TemplateResult result = new TemplateResult { MasterPageFile = "~/masterpage.master" };
    view.AddControl( "Body", new LiteralControl( "Hello world!" ) );
    return result;
  }
}

This would require a master page named materpage.master with at least one content placeholder named Body.

Real world applications
For real world applications you'd probably declare extension methods for Controller that setup the MasterPageFile and Theme as used by the site. I've found that these classes make it much easier to migrate from pure webforms to MVC. It allows you to use MVC for new developments while enabling reuse of existing controls.

[Update: 1 May 2009]
Source code is now available for download. Please read my post on Alanta.Mvc.

ASP.NET MVC strong typed routing

One of the more questionable practices in the ASP.NET MVC framework is that all routing to controllers (and views) is based on names; plain text strings. I'm assuming this is because the MVC framework is heavily influenced by existing MVC frameworks like Ruby on Rails, but I'm not so sure whether it's a good idea.

One of the first things I learned back in the days when I got started in software development is never to rely on strings; use strong typing wherever possible because the compiler can check types. It can't check strings.

ASP.NET MVC seems to violate this rule and instead promotes unit testing to validate routing decisions. While I'm convinced that unit testing is a good thing, I'm not at all comfortable with writing a unit test for something that a compiler can check. For example, I have a controller class named My.VeryCoolController. If I want to route requests to that controller I could set that up like this:
RouteTable.Routes.MapRoute( "coolstuff", "docoolstuff.aspx", new { controller = "VeryCool", action ="HelloWorld" } );
So the controller parameter refers to the VeryCoolController class by it’s name. Where I come from this is a very bad practice! In fact, pretty much all of the coding standards I've ever seen will explicitly forbid this. So, why not do this:
RouteTable.Routes.mapRoute<my.verycoolcontroller>( "coolstuff", "docoolstuff.aspx", new { action = "helloworld" );

In my opinion this is much more robust; the code won't even compile if I break it somehow.

Implementation
Since the ASP.NET MVC framework is completely setup to work with names in stead of type I've created some classes that do support routing based on types. This requires the following functionality:

  1. Extension methods to define a route using the controller’s type
  2. A route handler that can spawn a strong typed HttpHandler for the controller
  3. An HttpHandler that invokes the specified controller
An extension method for mapping a route using a controller type would look like this :
public static Route MapRoute<T>( this RouteCollection routes, string name, string url, object defaults, object constraints ) 
  where T : Controller, new() 
  { 
     Route route = new Route( url, new MvcRouteHandler<t>() ) 
       { 
         Defaults = new RouteValueDictionary( defaults ), 
         Constraints = new RouteValueDictionary( constraints ) 
        }; 

     // For compatibility with MvcHandler 
     route.Defaults.Add( "controller", typeof( T ).Name.Replace( "Controller", "" ) ); 
     routes.Add( name, route ); 
     return route; 

  } 
  
Note that all error handling has been removed from this snippet. Nothing spectacular here; this is pretty much what the stock extension methods shipped with ASP.NET MVC do. One important thing to note here is that setting a value for controller is required; otherwise this like RedirectToRouteResult will not work as you'd expect. Next up, implementing a custom route handler. Not too dificult either:
internal class MvcRouteHandler<TController> : System.Web.Routing.IRouteHandler 
  where TController : System.Web.Mvc.Controller, new() 
  { 
    public IHttpHandler GetHttpHandler( RequestContext requestContext ) 
    { 
      return new MvcHttpHandler( 
        new TController(), 
	requestContext ); 
    } 
  }
The code above instantiates a new controller of the required type and hands it over to an MvcHttpHandler which we'll create next. Before we do though, note that creating the controller like this requires it to have default (parameterless) constructor. If you need some kind of dependency injection you could delegate controller creation to an Inversion-of-Control container. Finally, the MvcHttpHandler mentioned above:
internal class MvcHttpHandler : IHttpHandler, 
System.Web.SessionState.IRequiresSessionState 
{ 
  public MvcHttpHandler( System.Web.Mvc.IController controller, System.Web.Routing.RequestContext context ) 
  { 
    _controller = controller; 
    _context = context; 
  } 

  public bool IsReusable 
  { 
    get { return false; } 
  } 

  public void ProcessRequest( HttpContext context ) 
  { 
    _controller.Execute( _context ); 
  } 

  System.Web.Mvc.IController _controller; 
  System.Web.Routing.RequestContext _context; 
}

A couple of things to point out here. First off, to support session state the handler must inherit from IRequiresSessionState. Secondly, notice that the Execute method does not use the HttpContext instance passed into the ProcessRequest method. Instead the RequestContext required by the controller is passed in to the constructor by the route handler and stored as a field. This also means that IsReusable must return false; the handler has state specific to a request and is therefore not reusable.

And then what?
That's it. The controller has all the mechanisms needed to dynamically invoke the method associated with the request. All of MVC's routing magic will work with this setup. I'll post a zip with the full code shortly.

Sources are available as part of the Alanta.Mvc project.