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

如何在非主方法中通过Results.File()返回文件?

问题根源分析

我一眼就看出问题所在了——你在主MapGet方法里调用CheckIfDownload后,完全没处理它返回的IResult,直接跳过继续执行后面的return了!哪怕CheckIfDownload已经生成了文件下载或者BadRequest的响应结果,主方法也会忽略这个结果,继续返回最后的Json响应,这就是为什么你调试时看到SendJsonFile执行了,但浏览器没收到文件的原因。

解决方案

你需要在主方法中检查CheckIfDownload的返回值:如果它返回了非null的IResult(说明需要返回下载文件或者错误),就直接把这个结果返回;只有当它返回null时,才继续执行生成Json的逻辑。

修改后的完整代码
app.MapGet("/", (HttpContext context) => {
    if (context.Request.Query.ContainsKey("amount")) {
        if (context.Request.Query["amount"].Count > 1) {
            return Results.BadRequest(new { Error = "The query parameter 'amount' may only be used once." });
        }
        if (int.TryParse(context.Request.Query["amount"], out int amount)) {
            if (amount <= 0) {
                return Results.BadRequest(new { Error = "The specified amount must be greater or equal to 1." });
            }
            var list = new List<string>();
            for (int i = 0; i < amount; i++) {
                list.Add(Ulid.NewUlid().ToString());
            }
            // 关键修改:检查CheckIfDownload的返回值,非null则直接返回
            var downloadResult = CheckIfDownload(context, (list, null));
            if (downloadResult != null)
            {
                return downloadResult;
            }
            return Results.Json(new { Ulids = list });
        } else {
            return Results.BadRequest(new { Error = "The specified amount is not a valid number." });
        }
    }
    string ulid = Ulid.NewUlid().ToString();
    // 同样,这里也要检查返回值
    var singleDownloadResult = CheckIfDownload(context, (null, ulid));
    if (singleDownloadResult != null)
    {
        return singleDownloadResult;
    }
    return Results.Json(new { Ulid = ulid });
});

static IResult? CheckIfDownload(HttpContext context, (List<string>? list, string? single) ulidListOrSingle) {
    if (context.Request.Query.ContainsKey("download")) {
        if (context.Request.Query["download"].Count > 1) {
            return Results.BadRequest(new { Error = "The query parameter 'download' may only be used once." });
        }
        if (context.Request.Query["download"] == "" || (bool.TryParse(context.Request.Query["download"], out bool download) && download)) {
            if (ulidListOrSingle.list != null) {
                return SendJsonFile(JsonSerializer.Serialize(ulidListOrSingle.list));
            }
            if (ulidListOrSingle.single != null) {
                return SendJsonFile(JsonSerializer.Serialize(ulidListOrSingle.single));
            }
            return Results.BadRequest(new { Error = "An unknown error occurred." });
        }
    }
    return null;
}

static IResult SendJsonFile(string data) {
    byte[] buffer = Encoding.UTF8.GetBytes(data);
    var stream = new MemoryStream(buffer);
    return Results.File(stream, "application/json", $"UlidGenerator_{DateTime.Now:MM-dd-yyyy_HH-mm-ss}.json");
}
额外说明

你的思路是对的——用IResult作为辅助方法的返回类型是ASP.NET Core极简API的标准写法,因为所有响应结果都应该通过IResult来统一处理。之前的问题完全是因为主方法没有“接住”辅助方法返回的结果,直接走了默认的Json返回逻辑。

另外,Results.BadRequest()这类方法返回的也是IResult,所以只要你在主方法中正确返回这些结果,就能正常触发对应的响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 10:03:11