You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C# Minimal API中实现HTTP HEAD请求功能?

HEAD

HTTP HEAD方法请求的是:使用HTTP GET方法请求同一URL时会返回的响应头。

例如,若某个URL对应大文件下载,HEAD请求可读取Content-Length头信息来检查文件大小,无需实际下载文件。

问题描述

我需要在Minimal API端点中实现HEAD请求的支持,但测试时选择HEAD动词会返回错误:

405 Method Not Allowed 

使用GET动词进行下载则正常工作。希望获得HEAD动词的实现示例或配置说明。

原GET端点代码如下:

app.MapGet(@"download/{fileName}", async (string fileName) =>
{
    var mimeType = "application/zip";
    var path = @$"e:\{fileName}.zip";
    var bytes = await File.ReadAllBytesAsync(path);

    return Results.File(bytes, mimeType, $"{fileName}.zip");
})
          .Produces(StatusCodes.Status200OK)
          .Produces(StatusCodes.Status404NotFound)
          .WithName($"GET {EndpointCategory} by Name")
          .WithTags(Tag);

解决方案

方式1:单独映射HEAD端点(推荐)

为同一个URL单独配置HEAD端点,仅处理响应头逻辑,避免读取整个文件内容:

// 保留原有的GET端点
app.MapGet(@"download/{fileName}", async (string fileName) =>
{
    var mimeType = "application/zip";
    var path = @$"e:\{fileName}.zip";
    if (!File.Exists(path))
    {
        return Results.NotFound();
    }
    var bytes = await File.ReadAllBytesAsync(path);
    return Results.File(bytes, mimeType, $"{fileName}.zip");
})
.Produces(StatusCodes.Status200OK)
.Produces(StatusCodes.Status404NotFound)
.WithName($"GET {EndpointCategory} by Name")
.WithTags(Tag);

// 新增HEAD端点,仅返回响应头
app.MapHead(@"download/{fileName}", (string fileName) =>
{
    var mimeType = "application/zip";
    var path = @$"e:\{fileName}.zip";
    if (!File.Exists(path))
    {
        return Results.NotFound();
    }
    var fileInfo = new FileInfo(path);
    
    var responseHeaders = new Dictionary<string, string>
    {
        {"Content-Length", fileInfo.Length.ToString()},
        {"Content-Type", mimeType}
    };
    
    return Results.Ok().WithHeaders(responseHeaders);
})
.Produces(StatusCodes.Status200OK)
.Produces(StatusCodes.Status404NotFound)
.WithName($"HEAD {EndpointCategory} by Name")
.WithTags(Tag);

方式2:让同一端点支持GET和HEAD

使用MapMethods指定允许的HTTP动词,ASP.NET会自动处理HEAD请求(仅返回响应头):

app.MapMethods(@"download/{fileName}", new[] { "GET", "HEAD" }, async (string fileName) =>
{
    var mimeType = "application/zip";
    var path = @$"e:\{fileName}.zip";
    if (!File.Exists(path))
    {
        return Results.NotFound();
    }
    var bytes = await File.ReadAllBytesAsync(path);
    return Results.File(bytes, mimeType, $"{fileName}.zip");
})
.Produces(StatusCodes.Status200OK)
.Produces(StatusCodes.Status404NotFound)
.WithName($"{EndpointCategory} by Name")
.WithTags(Tag);

注意:方式2虽然简便,但如果文件体积较大,GET逻辑中的File.ReadAllBytesAsync仍会将整个文件加载到内存,而HEAD请求不需要此操作。因此更推荐方式1,节省资源开销。

内容的提问来源于stack exchange,提问作者TheSloth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 00:50:20