如何在非主方法中通过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
相关产品推荐
相关产品推荐

