发起Post请求时遭遇405 Method Not Allowed异常的排查求助
问题分析与解决方案
核心错误点
你的代码存在4个关键问题,直接导致了405异常和请求失败:
- 请求地址错误:API的Post端点路由是
api/Invoice(基于控制器名+[HttpPost]特性),你写的api/Invoice/Post是错误路径,Postman用了正确地址所以能成功。 - HttpClient地址重复拼接:设置
BaseAddress为完整API地址后,又在PostAsJsonAsync中传入相同地址,导致最终请求地址是重复的无效路径。 - 请求内容双重序列化:先把
invoice转成StringContent,再传给PostAsJsonAsync,会导致框架把StringContent对象再次序列化,而非正确序列化Invoice模型。 - 响应处理逻辑错误:API返回的是PDF流,你却尝试读取为字符串并反序列化成
DataTable,完全不符合返回内容格式。
修正后的MVC调用代码
public async Task<FileStreamResult> Download(Invoice? invoice) { // 拆分根地址和端点,避免重复拼接 string apiBaseUrl = "https://localhost:7175/"; string apiEndpoint = "api/Invoice"; using (HttpClient client = new HttpClient()) { client.BaseAddress = new Uri(apiBaseUrl); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); // 直接传入Invoice对象,由PostAsJsonAsync自动序列化 HttpResponseMessage response = await client.PostAsJsonAsync(apiEndpoint, invoice); response.EnsureSuccessStatusCode(); // 直接读取API返回的PDF流 Stream pdfStream = await response.Content.ReadAsStreamAsync(); MemoryStream memoryStream = new MemoryStream(); await pdfStream.CopyToAsync(memoryStream); memoryStream.Position = 0; string mimeType = "application/pdf"; string fileName = $"Invoice_{invoice?.Id}.pdf"; return File(memoryStream, mimeType, fileName); } }
优化后的API控制器代码
确保控制器路由配置正确,返回规范的FileResult:
[Route("api/[controller]")] [ApiController] public class InvoiceController : ControllerBase { private readonly IGeneratePdf genPdf; public InvoiceController(IGeneratePdf genPdf) { this.genPdf = genPdf; } [HttpPost] public IActionResult Post([FromBody] Invoice invoice) { MemoryStream stream = genPdf.GeneratePdf(invoice); // 返回带Content-Type的FileResult,更符合Web API规范 return File(stream, "application/pdf"); } }
确认CORS配置(API项目Program.cs)
确保CORS策略正确允许MVC项目的域名:
var builder = WebApplication.CreateBuilder(args); // 添加CORS策略 builder.Services.AddCors(options => { options.AddPolicy("AllowMvcOrigin", policy => policy.WithOrigins("https://localhost:xxxx") // 替换为你的MVC项目运行地址 .AllowAnyHeader() .AllowAnyMethod()); }); builder.Services.AddControllers(); var app = builder.Build(); // 启用CORS(必须放在UseRouting之后,UseAuthorization之前) app.UseCors("AllowMvcOrigin"); app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
内容的提问来源于stack exchange,提问作者jenlee123
相关产品推荐
相关产品推荐

