如何记录.NET静态文件服务器的进度

问题描述 投票:0回答:1

有没有人见过可以从 ASP.NET Core Web 应用程序的服务器端检查文件下载进度的解决方案?我的用例是:

  1. 客户端 GUI 应用程序使用本文底部的代码启动 Web 服务器。
  2. 另一个线程命令物联网设备下载文件。
  3. GUI 应用程序显示下载进度。

有人知道我可以使用任何钩子或事件来通知 GUI 上的某些进度指示器吗?请告诉我!非常感谢。

这是代码。这是一个非常小的函数,使用基本的 .NET Core 提供一些静态文件:

private void RunServer(string configPath)
{
    var builder = WebApplication.CreateBuilder();
    var app = builder.Build();

    app.UseStaticFiles(new StaticFileOptions()
    {
        FileProvider = new PhysicalFileProvider(configPath),
        ServeUnknownFileTypes = true,
        DefaultContentType = "text/plain"
    });

    app.Run(FileServer);
}

我尝试使用内置的

OnPrepareResponse
事件,但这仅在发送标头之前显示文件请求,并且无法让我深入了解下载本身。我还阅读了静态文件中间件的文档,但没有看到任何适合此用例的内容。

任何事情都有帮助!再次感谢您。

c# asp.net-core asp.net-core-webapi
1个回答
0
投票

您可以创建一个中间件来提供文件服务并在读取操作期间宣布常规事件:


public class DownloadProgressAnnouncingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IFileProvider _fileProvider;

    public DownloadProgressAnnouncingMiddleware(RequestDelegate next, string rootDirectory)
    {
        _next = next;
        _fileProvider = new PhysicalFileProvider(rootDirectory);
    }

    public async Task Invoke(HttpContext context)
    {
        var path = context.Request.Path.Value;

        // Check if the request path starts with "/files"
        if (path.StartsWith("/files"))
        {
            var fileInfo = _fileProvider.GetFileInfo(path[6..]);

            if (fileInfo.Exists)
            {
                using (var fileStream = fileInfo.CreateReadStream())
                {
                    var buffer = new byte[8192];
                    int bytesRead;
                    long totalBytesRead = 0;

                    // Read the file and raise progress events
                    while ((bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                    {
                        totalBytesRead += bytesRead;
                        // Raise progress event
                        Console.WriteLine($"Bytes read: {totalBytesRead} / {fileInfo.Length}");
                        await context.Response.Body.WriteAsync(buffer, 0, bytesRead);
                    }
                }
                return;
            }
        }

        await _next(context);
    }
}

将其连接到新的 netcore REST API 项目中:


using Microsoft.Extensions.FileProviders;

namespace WebApplication1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.

            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();


            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }

            app.UseMiddleware<DownloadProgressAnnouncingMiddleware>("C:\\temp");

            app.MapControllers();

            app.Run();
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.