views:

464

answers:

2

Sometimes J2EE-savvy people look at ASP.NET and wonder, where's the support for deploying an app as a single unit? JSP/Servlet apps can be deployed as WAR files, with all pages, content, metadata, and code in that single archive. The war file can be versioned, easily moved around. There's an assurance that the entire app is contained in a single unit.

That's not a mainstream approach for ASP.NET. What do people do? Do they resort to copying directories and all the myriad files? Is this just not a problem for ASP.NET developers?

(this is sort of a cheat, because I'm going to suggest my own answer)

+2  A: 

Although not a mainstream approach in ASP.NET, this is very possible, using a construct called the VirtualPathProvider for ASP.NET. With it, you can serve website content out of things that are not the filesystem. For one example, you could serve an ASP.NET website directly out of a ZIP file, without unzipping the files to disk, first.

Here's a download that demonstrates or illustrates the concept, using the DotNetZip library to assist ASP.NET in pulling content out of the zip.

The interesting code bits:

using Ionic.Zip;

namespace Ionic.Zip.Web.VirtualPathProvider
{
    public class ZipFileVirtualPathProvider : System.Web.Hosting.VirtualPathProvider
    {
        ZipFile _zipFile;

        public ZipFileVirtualPathProvider (string zipFilename)
            : base () {
            _zipFile =  ZipFile.Read(zipFilename);
        }

        ~ZipFileVirtualPathProvider () {
            _zipFile.Dispose ();
        }

        public override bool FileExists (string virtualPath)
        {
            string zipPath = Util.ConvertVirtualPathToZipPath (virtualPath, true);
            ZipEntry zipEntry = _zipFile[zipPath];

            if (zipEntry != null)
            {
                return !zipEntry.IsDirectory;
            }
            else
            {
                // Here you may want to return Previous.FileExists(virtualPath) instead of false
                // if you want to give the previously registered provider a process to serve the file
                return false;
            }
        }

        public override bool DirectoryExists (string virtualDir)
        {
            string zipPath = Util.ConvertVirtualPathToZipPath (virtualDir, false);
            ZipEntry zipEntry = _zipFile[zipPath];

            if (zipEntry != null)
            {
                return zipEntry.IsDirectory;
            }
            else
            {
                // Here you may want to return Previous.DirectoryExists(virtualDir) instead of false
                // if you want to give the previously registered provider a chance to process the directory
                return false;
            }
        }

        public override VirtualFile GetFile (string virtualPath) {
            return new ZipVirtualFile (virtualPath, _zipFile);
        }

        public override VirtualDirectory GetDirectory (string virtualDir)
        {
            return new ZipVirtualDirectory (virtualDir, _zipFile);
        }

        public override string GetFileHash(string virtualPath, System.Collections.IEnumerable virtualPathDependencies)
        {
            return null;
        }

        public override System.Web.Caching.CacheDependency GetCacheDependency(String virtualPath, System.Collections.IEnumerable virtualPathDependencies, DateTime utcStart)
        {
            return null;
        }
    }
}

The VPP construct works with ASP.NET 2.0 or later, works with any website. You can of course adapt the idea to source content from a database, a CMS, or ... ??

Cheeso
Why would you ever want to do this ????
Chad Grant
To make site deployment simpler. Just one file. easy checksum for verification. etc.
Cheeso
+1  A: 

Part of the solution is embedded resources. That takes care of all the static files.

Part of the solution is using a web deployment project, compiling all pages (i.e. website not-updatable) into a single assembly. That takes care of all the .cs files.

So what is left is a .dll in bin, supporting .dll files and the .aspx stub files. IIS by default wants the aspx file to exist before it attempts to server it up, hence the stub.

MatthewMartin