Upgrading Your Server Implementation to WebDAV Server Engine .NET v3

If you have a previous release version of Engine v3 installed, you do not need to uninstall it to use the new version. Both versions can exist side by side, including WebDAV Wizards for Visual Studio.

The new version will be installed in a separate folder, by default to C:\Program Files (x86)\IT Hit\WebDAV Server Engine\v3.x.x.x\. The projects created by the older version of WebDAV wizards for Visual Studio will continue to reference the older version of ITHit.WebDAV.Server.dll. If you want to use the new version of ITHit.WebDAV.Server.dll in the projects created by an older version of WebDAV wizards for Visual Studio, you must manually update the reference to dll in your project. By default the ITHit.WebDAV.Server.dll is installed to C:\Program Files (x86)\IT Hit\WebDAV Server Engine\v3.x.x.x\Server\bin folder.

Upgrade From SDK V3 Beta to SDK V3 Release

The Beta version of Engine V3 SDK cannot run side by side with the Release version. To install the Release version of SDK, you must first uninstall the Beta version of SDK.

Upgrade from Engine V1 and V2 to Engine V3

Below is the summary of changes in V3 comparing to previous versions:

V1, V2 EntityCorresponding V3 Entity
Class Engine DavEngine, DavContextBase
Interface IResource IFile
Interface ILockNull Removed, replaced by IFolder.CreateFile and ILock.Lock calls.
Interface IFolderLock ILock
Class WebDAVResponse Removed, to generate custom response throw DavException
Class Request DavRequest
Interface IResponse DavResponse
Method Engine.GetHierarchyItem DavContextBase.GetHierarchyItem
Property Engine.IgnoreExceptions Removed, engine now always throws exceptions if any exception occurs.
Method IResource.WriteToStream IFile.Read
Method IResource.SaveFromStream IFile.Write
Property IFolder.Children IItemCollection.GetChildren
Method IResumableUpload.SaveFromStream IFile.Write
Module ResumableUploadModule ITHitPutUploadProgressAndResumeModule, ITHitPostUploadProgressModule

Engine Сlass

In the new version, some of the of the functionality of the Engine class is moved to the new DavContextBase class. The Engine class itself is renamed to DavEngine and marked as sealed. The DavEngine.Run method is now thread-safe, so you can create a single instance of DavEngine class, save it in the application state and reuse it, calling Run method in each request.

Now, you do not need to derive your class from Engine no more, instead you will create a class derived from DavContextBase to implement DAV context. The Engine.GetHierarchyItem method is moved to DavContextBase class, but its semantics and parameters are preserved. In each request, you must create a separate instance of your class derived from DavContextBase and pass it to DavEngine.Run method. Previously the Run method provided 3 overloads, optimized for IIS/ASP.NET, HttpListener and any other environment. Now this functionality is provided by 3 DavContextBase constructors. The generic request and response are now represented by DavRequest and DavResponseclasses. In case you need to create your own request and response classes you will derive your classes from them, similarly how it was with Request and IResponse in previous versions.

The license is now set via DavEngine.License property, you do not need to override the method for reading the license no more.

Below is the example of the example HttpHandler utilizing the new DavEngine class:

public class DavHandler : IHttpHandler
{
    ...
    public void ProcessRequest(HttpContext httpContext)   
    {
        context.Response.BufferOutput = false;
 
        DavEngine engine = new DavEngine();
        engine.License = @"<?xml version=""1.0""...
        var myContext = new MyDavContext(httpContext);
        engine.Run(myContext);
    }
}
 
public class MyDavContext : DavContextBase
{
    private readonly string repositoryPath = "C:\\MyStorage\\";
 
    public MyDavContext(HttpContext httpContext) : base(httpContext)
    {
    }
 
    public override IHierarchyItem GetHierarchyItem(string path)
    {
        string fullPath = repositoryPath + path.Replace('/', '\\');
 
        DirectoryInfo directory = new DirectoryInfo(fullPath);
        if (directory.Exists)
            return new DavFolder(directory); // implements IFolder
 
        FileInfo file = new FileInfo(fullPath);
        if (file.Exists)
            return new DavFile(file); // implements IFile
 
        return null; // neither file nor folder was found in the repository
    }
}

Files and Folders

IResource is renamed to IFile, that is now derived from IContent interface. All members of IResource are moved IContent interface. The WriteToStream and SaveFromStream are renamed to Read and Write. The IResumableUpload.SaveFromStream method is removed, and its functionality now provided by IContent.Write method. The IContent.Write is now always called both when entire file is submitted to the server and when only a file segment is uploaded.

IFolder is now derived from IItemCollection. The IFolder.Children property is replaced by IItemCollection.GetChildren method that now returns IEnumerable instead of the array. The new parameter passed to GetChilderen provides a hint of what properties were requested by the client, so you can optimize your requests to storage and load only required properties.

Now the value returned from IHierarchyItem.Path is not being encoded by the Engine (there is no way to automatically detect which character should be encoded and which is not). Now you must encode each segment between slashes yourself in IHierarchyItem.Path implementation. The library provides EncodeUtil to help you with encoding. Unlike HttpUtility class provided with .Net, this class encodes '+' character.

Interfaces for Locks Support

The ILockNull and IFolderLock interfaces are removed. The library provides any lock-null item abstraction no more, it is considered obsolete by new RFC 4918 WebDAV specification. However, the library supports any RFC 2518 clients. When a lock-null item is created (LOCK request is issued on the item that does not exist), the server creates a zero-length file and locks it, calling IFolder.CreateFile() and ILock.Lock().

Instead of IFolder.Lock interface now you have to add ILock interface on your folder items. You can live the implementation blank as most WebDAV clients never lock folders, it serves only as a marker that your server supports Class 2.

WebDAV Response Codes

The WebDAVResponse class is removed. There is no more need to return alternative responses depending on zero/non-zero file length or any other conditions. Unless your implementation throws any exception, the IT Hit WebDAV Server Engine assumes that the request was processed successfully and returns response code specified in WebDAV or other standards. In case you need to return any custom response code you can throw DavException.

ResumableUploadModule

The functionality of ResumableUploadModule is replaced by 2 modules:

  1. ITHitPutUploadProgressAndResumeModule - enables unbuffered upload of files when PUT verb is used and the server is using ASP.NET 2.0 pool. It is required if you are implementing resumable upload interfaces. This module also improves upload performance in case of ASP.NET 2.0 pool regardless of resumable upload implementation. It is not required if you are using .Net 4.0 pool or later, and is ignored, in this case.
  2. ITHitPostUploadProgressModule- enables unbuffered POST upload of files and processes file content submitted to server by IT Hit Ajax Browser only when Internet Explorer or legacy browser is used. Note that module does not process POST requests (postbacks) submitted by ASP.NET pages.

Transactions

The Engine.IgnoreExceptions property is removed. Unlike previous versions DavEngine.Run now throws exceptions if any exception in your interfaces implementations occurred. To commit or rollback transactions, it is recommended to implement DavContextBase.BeforeResponse method. This method is called when engine finished processing and is ready to write a response. To see if any exception has occurred, you will analyze the DavContextBase.Exceptionproperty.