.NET Server

Creating a Custom WebDAV Method Handler

In this article

Creating a Custom WebDAV Method Handler

With IT Hit WebDAV Server Engine for .NET you can create a custom method handler to process any custom HTTP verbs as part of the Engine processing pipeline. The most typical verb that you would want to process in your WebDAV server that is not handled by the Engine is a GET request. In this article, we will describe how to create it.

When a WebDAV server is accessed using a desktop WebDAV clients such as Microsoft mini redirector/Web Folders or Mac OS X Finder, the desktop WebDAV client never submits GET request to a WebDAV folder, so if you are using desktop clients only, you do not need to care about the scenario described here.

However, a user may also access your WebDAV server by typing a URL of the WebDAV server in a web browser. In this case, you would want to display some custom web page that contains information about how to connect to your server, list folder contents, or display other information.

When a user types WebDAV server root URL or URL of some folder (such as https://myserver/somefolder/) in a web browser address bar and hits 'Go', the web browser submits a GET request to a WebDAV folder. The GET requests submitted to WebDAV folders are not regulated by WebDAV protocol and are not processed by the IT Hit WebDAV Server. To display some custom web page, you must implement a custom method handler and register it with the Engine.

To register a handler, call DavEngineAsync.RegisterMethodHandler method passing the HTTP method name and object instance implementing IMethodHandler interface. The original handler, if any, is returned from RegisterMethodHandler method. An example below processes and displays an ASP.NET web page in response to a GET request to a folder:

DavEngine engine = new DavEngine();
//...
var handler = new MyCustomGetHandler();
handler.OriginalHandler = engine.RegisterMethodHandler("GET", handler);
engine.Run(myContext);
class MyCustomGetHandler : IMethodHandler
{
public IMethodHandler OriginalHandler { get; set; }
public bool EnableOutputBuffering
{
get { return false; }
}
public bool EnableOutputDebugLogging
{
get { return false; }
}
public bool EnableInputDebugLogging
{
get { return false; }
}
///<summary>
/// Handles GET request.
///</summary>
///<param name="context">Instace of <see cref="DavContextBase"/>.</param>
///<param name="item">Instance of <see cref="IHierarchyItem"/> which was returned by
///<see cref="DavContextBase.GetHierarchyItem"/> for this request.</param>
public void ProcessRequest(DavContextBase context, IHierarchyItem item)
{
if (item is IFolder)
{
// Remember to call EnsureBeforeResponseWasCalled here if your context implementation
// makes some useful things in BeforeResponse.
context.EnsureBeforeResponseWasCalled();
Page page = (Page)System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(
"~/MyCustomHandlerPage.aspx", typeof(Page));
page.ProcessRequest(HttpContext.Current);
}
else
{
OriginalHandler.ProcessRequest(context, item);
}
}
public bool AppliesTo(IHierarchyItem item)
{
return item is IFolder || OriginalHandler.AppliesTo(item);
}
}
Private engine As DavEngine = New DavEngine()
'...
Private handler As MyCustomGetHandler = New MyCustomGetHandler();
handler.OriginalHandler = engine.RegisterMethodHandler("GET", handler);
engine.Run(myContext);
Class MyCustomGetHandler
Inherits IMethodHandler
Public Property OriginalHandler As IMethodHandler
Public ReadOnly Property EnableOutputBuffering As Boolean
Get
Return False
End Get
End Property
Public ReadOnly Property EnableOutputDebugLogging As Boolean
Get
Return False
End Get
End Property
Public ReadOnly Property EnableInputDebugLogging As Boolean
Get
Return False
End Get
End Property
'<summary>
' Handles GET request.
'</summary>
'<param name="context">Instace of <see cref="DavContextBase"/>.</param>
'<param name="item">Instance of <see cref="IHierarchyItem"/> which was returned by
'<see cref="DavContextBase.GetHierarchyItem"/> for this request.</param>
Public Sub ProcessRequest(ByVal context As DavContextBase, ByVal item As IHierarchyItem)
If TypeOf item Is IFolder Then
' Remember to call EnsureBeforeResponseWasCalled here if your context implementation
' makes some useful things in BeforeResponse.
context.EnsureBeforeResponseWasCalled()
Dim page As Page = CType(System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath("~/MyCustomHandlerPage.aspx", GetType(Page)), Page)
page.ProcessRequest(HttpContext.Current)
Else
OriginalHandler.ProcessRequest(context, item)
End If
End Sub
Public Function AppliesTo(ByVal item As IHierarchyItem) As Boolean
Return TypeOf item Is IFolder OrElse OriginalHandler.AppliesTo(item)
End Function
End Class

The following example lists folder content:

public void ProcessRequest(DavContextBase context, IHierarchyItem item)
{
if (item is IFolder)
{
context.EnsureBeforeResponseWasCalled();
// in case of HttpListener you must also set content lenght: context.Response.ContentLength = 12345;
context.Response.ContentType = "text/html";
using (var writer = new StreamWriter(context.Response.OutputStream))
{
writer.Write("<html><head></head><body>");
IEnumerable<IHierarchyItem> items = ((IFolder)item).GetChildren(null);
foreach (IHierarchyItem hierarchyItem in items)
{
writer.Write("<a href='" + context.Request.ApplicationPath.TrimEnd('/') + hierarchyItem.Path + "'>");
writer.Write(hierarchyItem.Name);
writer.Write("</a><br/>");
}
writer.Write("</body></html>");
}
}
else
{
OriginalHandler.ProcessRequest(context, item);
}
}
Public Sub ProcessRequest(ByVal context As DavContextBase, ByVal item As IHierarchyItem)
If TypeOf item Is IFolder Then
context.EnsureBeforeResponseWasCalled()
' in case of HttpListener you must also set content lenght: context.Response.ContentLength = 12345;
context.Response.ContentType = "text/html"
Using writer = New StreamWriter(context.Response.OutputStream)
writer.Write("<html><head></head><body>")
Dim items As IEnumerable(Of IHierarchyItem) = (CType(item, IFolder)).GetChildren(Nothing)
For Each hierarchyItem As IHierarchyItem In items
writer.Write("<a href='" & context.Request.ApplicationPath.TrimEnd("/"c) + hierarchyItem.Path & "'>")
writer.Write(hierarchyItem.Name)
writer.Write("</a><br/>")
Next
writer.Write("</body></html>")
End Using
Else
OriginalHandler.ProcessRequest(context, item)
End If
End Sub

Next Article:

Creating a WebDAV Property Handler