Click or drag to resize
Portable WebDAV Library

Welcome to the Portable WebDAV Library

The Portable WebDAV Library is a strongly typed, async WebDAV client library which is fully compliant to RFC 4918, RFC 4331, Additional WebDAV Collection Properties and some IIS WebDAV specific properties. It is implemented as .NETStandard 1.1 library in oder to be used on any platform supporting .NETStandard 1.1.

Obtaining the library

There is a NuGet package available: Just search for 'PortableWebDavLibrary' in the 'Manage NuGet Packages...' window in Visual Studio. You can also find the package here.

If you prefer the manual installation method, you can find the current release as ZIP file on the GitHub release page.

Getting Started

To get started, add a reference to DecaTec.WebDav.dll to your project.

Usage

See the following code which uses a WebDavSession to retrieve the content of a folder:

There are two levels of abstractions included in this library: A low level abstraction (class WebDavClient) which supports direct access to a WebDAV server and a higher level of abstraction (class WebDavSession) which hides most of the direct WebDAV communication and provides an easy access to WebDAV resources.

WebDavSession

The WebDavSession should be sufficient for most use cases regarding WebDAV access. It provides a high level of abstraction and hides most of the WebDAV specific details (like sending or receiving XML content strings) and supports an easy access to WebDAV servers.

See the following code which uses a WebDavSession to retrieve the content of a folder:

C#
// The base URL of the WebDAV server.
var webDavServerUrl = "http://www.myserver.com/webdav/";

// Specify the user credentials and use it to create a WebDavSession instance.
var credentials = new NetworkCredential("MyUsername", "MyPassword");
var webDavSession = new WebDavSession(@"http://www.myserver.com/webdav/", credentials);
var items = await webDavSession.ListAsync(@"MyFolder/");

foreach (var item in items)
{
    // Handle the response (list of WebDavSessionListItems), e.g item.Uri is the URL of an item (folder or file).
}

By default, WebDavSession uses a so called 'allprop' when listing the contents of a folder. The WebDAV server should return all known properties. Which properties are returned depends on the WebDAV server. If not all of the expected properties are returned or you only need a subset of all known properties, you can specify another PropFind type when calling ListAsync:

C#
var propFind = PropFind.CreatePropFindWithEmptyProperties(PropNameConstants.IsHidden, PropNameConstants.DisplayName, PropNameConstants.Name, PropNameConstants.GetContentType, PropNameConstants.CreationDate, PropNameConstants.ResourceType, PropNameConstants.GetLastModified, PropNameConstants.GetContentLength);
var items = await webDavSession.ListAsync(@"MyFolder/", propFind);

foreach (var item in items)
{
    // Handle the response (list of WebDavSessionListItems); only the properties specified with propFind should be returned by the server.
}

WebDavClient

When the WebDavSession is not sufficient for specific operations, there is also a low level WebDAV access: WebDavClient. This class inherits from System.Net.Http.HttpClient and offers all WebDAV specific operations in the same style as the HttpClient. By using WebDavClient, you can use all of the WebDAV operations specified in RFC 4918. The use of WebDavClient is recommended for users who are familiar with the WebDAV specification.

See the following code which uses a WebDavClient to retrieve the content of a folder:

C#
// The base URL of the WebDAV server.
var webDavServerUrl = @"http://www.myserver.com/webdav/";

// Specify the user credentials and pass it to a HttpBaseProtocolFilter.
var credentials = new NetworkCredential("MyUserName", "MyPassword");

var httpClientHandler = new HttpClientHandler()
{
    Credentials = credentials
};

// Use the HttpClientHandler (with credentials) to create a new WebDavClient.
var webDavClient = new WebDavClient(httpClientHandler);

// Create a PropFind object with represents a so called 'allprop' request.
var pf = PropFind.CreatePropFindAllProp();
var response = await webDavClient.PropFindAsync(webDavServerUrl + @"/MyFolder/", WebDavDepthHeaderValue.Infinity, pf);

// You could also use an XML string directly for use with the WebDavClient.
//var xmlString = "<?xml version=\"1.0\" encoding=\"utf-8\"?><D:propfind xmlns:D=\"DAV:\"><D:allprop /></D:propfind>";
//var response = await webDavClient.PropFindAsync(webDavServerUrl + @"/MyFolder/", WebDavDepthHeaderValue.Infinity, xmlString);

// Use the WebDavResponseContentParser to parse the response message and get a MultiStatus instance (this is also an async method).
var multistatus = await WebDavResponseContentParser.ParseMultistatusResponseContentAsync(response.Content);

// Now you can use the MultiStatus object to get access to the items properties.
foreach (var responseItem in multistatus.Response)
{
    // Handle propfind multistatus response, e.g responseItem.Href is the URL of an item (folder or file).
}

// Dispose the WebDavClient when it is not longer needed.
webDavClient.Dispose();

Locking

The Portable WebDAV Library also supports WebDAV locking.

When using a WebDavClient, the locking has to be managed by the calling code, i.e. the handling of lock tokens etc.

Using a WebDavSession makes WebDAV locking pretty easy, because the WebDavSession handles all the locking mechanism by itself. As an example: When the WebDavSession was used to lock a folder, all subsequent operations affecting the locked file or folder, no lock specific details have to be provided (e.g. you do not have to specify a lock token). This is all handled internally in the WebDavSession itself.

For example code demonstrating locking with WebDavClient or WebDavSession, see the documentation of these classes.

WebDAV object model

Most communication regarding WebDAV is realized with XML strings sent or received in the content of requests or responses. The library contains the WebDAV object model implemented in classes/enums, so there is no need to build up or parse any XML strings directly. Of course you can also use XML strings directly.

As an example: For sending a so called 'allprop' request, you'll need an XML content in the request which looks like this:

<?xml version="1.0" encoding="utf-8"?>
<D:propfind xmlns:D="DAV:">
     <D:allprop />
</D:propfind>

When sending such a WebDAV request, you can simply use the XML string directly:

C#
var xmlString = "<?xml version=\"1.0\" encoding=\"utf-8\"?>...."

All methods which require such an XML string in the request content will accept this XML string.

But you can also use the WebDAV object model classes integrated in this library:

C#
PropFind pf = PropFind.CreatePropFindAllProp();

This will create an 'allprop' PropFind object which can be directly passed to the corresponding method in the WebDavClient. Many classes of the WebDAV object model contain static methods for creating standard WebDAV request contents. Keep in mind that the WebDAV object model implemented in this library can only be used with the WebDavClient class. When using the WebDavSession class, there is no need to bother about the content of WebDAV requests/responses, thus the WebDAV object model is not needed in this case.

Development

For development, you will need:

Unit tests

The solution contains unit tests (testing single units of the library), but also unit integration tests, which will test the library against a specific WebDAV server (e.g. a local IIS web server with WebDAV enabled). These unit tests are implemented as Unit Test Apps (Universal Windows).

Important: In order to run the unit integrations tests, information about a specific WebDAV server have to be provided in a configuration file. This has to be a file named 'TestConfiguration.txt' located in the unit integration test project's output folder. This file has to contain exactly three lines:

  • The user name

  • The password

  • The URL of a valid WebDAV server folder

If this configuration file is not present, all unit integration tests will fail!

See Also

Other Resources