Simon
Simon

Reputation: 127

Trying to add WebDAV support to ASP.NET Core Web API

On the server, I run an ASP.NET Core Web API. This API is used for an app and web interface to provide necessary Information. One of the information is contact information.

Now I want to sync my contact information with my smartphone's address book without an extra app. I choose WebDAV to achieve this.

The problem is that I have problems to extend the ASP.NET Core Web API with WebDAV because of the custom HttpAttribute like PROPFIND. Does somebody know a solution to add WebDAV?

This is my controller:

using Microsoft.AspNetCore.Mvc;

namespace Playground.Controllers
{
    [Route("api/webdav")]
    [ApiController]
    public class WebDAVController : ControllerBase
    {
        private readonly string _baseDirectory = Path.Combine(Directory.GetCurrentDirectory(), "WebDAVData");

        public WebDAVController()
        {
            // Ensure base directory exists
            if (!Directory.Exists(_baseDirectory))
            {
                Directory.CreateDirectory(_baseDirectory);
            }
        }

        // PROPFIND - Retrieve properties (a simple version)
        [AcceptVerbs("PROPFIND")]
        public IActionResult Propfind([FromQuery] string path)
        {
            var fullPath = Path.Combine(_baseDirectory, path ?? "");

            if (!System.IO.File.Exists(fullPath) && !Directory.Exists(fullPath))
            {
                return NotFound();
            }

            // Return file or folder properties (you can extend this to include more detailed properties)
            var fileInfo = new FileInfo(fullPath);

            var properties = new Dictionary<string, string>
            {
                { "CreationDate", fileInfo.CreationTime.ToString() },
                { "LastModified", fileInfo.LastWriteTime.ToString() },
                { "Size", fileInfo.Length.ToString() }
            };

            return Ok(properties);
        }
    }
}

Edit (06.01.2025): My current issue is that I can run the project but it is not possible for me to make a call to PROFIND:

curl -X PROPFIND http://localhost:5242/api/webdav/yourfile.txt -i
HTTP/1.1 404 Not Found
Content-Length: 0
Date: Mon, 06 Jan 2025 08:22:47 GMT
Server: Kestrel

Other calls on the API work fine:

curl -X GET http://localhost:5242/WeatherForecast/GetWeatherForecast
[{"date":"2025-01-07","temperatureC":-5,"summary":"Freezing","temperatureF":24},{"date":"2025-01-08","temperatureC":35,"summary":"Chilly","temperatureF":94},{"date":"2025-01-09","temperatureC":49,"summary":"Bracing","temperatureF":120},{"date":"2025-01-10","temperatureC":41,"summary":"Bracing","temperatureF":105},{"date":"2025-01-11","temperatureC":50,"summary":"Balmy","temperatureF":121}]

Here the log (I replaced the Content root path by *** manually for this post)

info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5242
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: ***
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
      Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException: The "PROPFIND" HTTP method is not supported.
         at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GenerateOperations(IEnumerable`1 apiDescriptions, SchemaRepository schemaRepository)
         at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GeneratePaths(IEnumerable`1 apiDescriptions, SchemaRepository schemaRepository)
         at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwaggerDocumentWithoutFilters(String documentName, String host, String basePath)
         at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwaggerAsync(String documentName, String host, String basePath)
         at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
         at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

Upvotes: 0

Views: 54

Answers (1)

Ruikai Feng
Ruikai Feng

Reputation: 11621

You need a filename section in your route,for example:

[ApiController]
[Route("api/webdav")]
public class TestController : ControllerBase
{
    public TestController()
    {
        
    }

    
    [AcceptVerbs("PROPFIND")]
    [Route("{filename}")]
    public IActionResult PROPFIND(string filename)
    {








        //..........
        
    }
}

The endpoint could be hit on myside now:

enter image description here

Upvotes: 0

Related Questions