Search code examples
json.net-6.0ms-wopiminimal-apisoffice-web-app

How to return an office document to OfficeOnline from WOPI API?


I am trying to use C# minimal API to develop a WOPI API for office online and on returning file to client i am always getting this error messages:

"Timeout are not supported on this stream".

I am using 'application/octet-stream' HTTP Header.


Solution

  • As you may know it is not possible for JsonSerializer to serialize a stream to return it as response, you have to load your file into byte[] afterward you put it in response body using code like this:

        FileInfo fileInfo = new FileInfo(filePath);
        FileStream fs = fileInfo.OpenRead();
        byte[] content = fs.ReadBytesAsync();
    

    and then in returning part:

        httpContext.Response.ContentType = MediaTypeNames.Application.Octet;
        return HttpContext.Response.Body.Write(content,0,content.Lenght)
    

    of course second part of code should take place in an extension method for Result.Extension somthing like this:

    static class FileResultExtension
    {
        public static IResult File(this IResultExtensions resultExtensions, byte[] fileResult)
        {
            ArgumentNullException.ThrowIfNull(resultExtensions);
    
            return new FileResult(fileResult);
        }
    }
    
    class FileResult : IResult
    {
        private readonly byte[] _fileResult;
    
        public FileResult(byte[] fileResult)
        {
            _fileResult = fileResult;
        }
    
        public Task ExecuteAsync(HttpContext httpContext)
        {
            httpContext.Response.ContentType = MediaTypeNames.Application.Octet;
            return httpContext.Response.Body.WriteAsync(_fileResult,0,_fileResult.Length);
        }
    }
    

    and use it in Program.cs like this:

    app.MapGet("/wopi/files/{id}/contents", (FilesService fileService, string id) =>
    {
        var result = fileService.GetFile(id).Result;
        MemoryStream memoryStream = new MemoryStream();
        memoryStream.Write(result, 0, result.Length);
        return Results.Extensions.File(result);
    }).WithName("GetFile");