Angular17调用ASP.NET Core共享文件夹检查API报404错误
背景
原AngularJS项目调用API的代码:
$http.get(`${uriApi}api/PDS/CheckDirectoryExistance?path=` + encodeURIComponent(dirPath)) .then(response => { if (response.data.ok) { docFound = true; LoadRootLevel(dirPath); Promise.resolve() } /*My Code Continues*/ }) .catch(error => { if (!alertShown) { docFolderFound = false; console.error("Error checking directory existence:", error); alert("There's no process documentation created for '" + $scope.partNo + "'\nPlease verify that this is correct or ask your supervisor to provide the documentation.\nEvaluating folders: \n" + dirs2 + "\n\nNo existe documentacion creada para el numero de parte '" + $scope.partNo + "'\nPor favor verifique que esto sea correcto o solucite a su supervisor la creacion de la documentacion"); alertShown = true; } });
迁移到Angular17与ASP.NET Core后,API代码:
[HttpGet("CheckDirectoryExistance/{path}")] public ActionResult CheckDirectoryExistance(string path) { try { bool directoryExists = Directory.Exists(path); return Ok(new { ok = directoryExists }); } catch(Exception ex) { return NotFound(ex); } }
新的Angular17调用代码:
let dirs = []; let dirPath = this.path + this.workSpaceInfo.userCell + "\\" + this.itemsInfo.partNo; let alertShown = false; console.log("DirPath? ", dirPath); try { let response = await this.http.get(`api/PDSWorker/CheckDirectoryExistance/` + encodeURIComponent(dirPath)).toPromise(); if (response == true) { docFound = true; this.LoadRootLevel(dirPath); console.log("directory found from response"); } /* My code Continues*/ } catch (error) { console.error("Error checking directory existence general catch:", error); }
错误信息
GET https://localhost:44359/api/PDSWorker/CheckDirectoryExistance/%5C%5CSharedFile01%5CPDS%5CX405%5CSt6%5C284A1733-170 404 (Not Found)
Error checking directory existence general catch:
message: "Http failure response for https://localhost:44359/api/PDSWorker/CheckDirectoryExistance/%5C%5CSharedFile01%5CPDS%5CX405%5CSt6%5C284A1733-170: 404 OK"
name: "HttpErrorResponse"
ok: false
status: 404
statusText: "OK"
url: "https://localhost:44359/api/PDSWorker/CheckDirectoryExistance/%5C%5CSharedFile01%5CPDS%5CX405%5CSt6%5C284A1733-170"
已尝试的操作
- 确认传入API的路径参数正确且真实存在
- 在API中设置断点但从未触发
- 将API从一个控制器迁移至另一个
- 控制器中的其他API可正常工作,但该API不行
解决方案
1. 改用查询参数传递路径(推荐)
ASP.NET Core的路由会把转义后的反斜杠%5C解析为路径分隔符,导致{path}参数无法匹配完整的共享路径。最稳妥的方式是沿用原AngularJS的查询参数传递方式:
修改API代码
// 移除路径参数,改用FromQuery获取参数 [HttpGet("CheckDirectoryExistance")] public ActionResult CheckDirectoryExistance([FromQuery] string path) { try { bool directoryExists = Directory.Exists(path); return Ok(new { ok = directoryExists }); } catch(Exception ex) { return NotFound(ex); } }
修改Angular调用代码
let dirs = []; let dirPath = this.path + this.workSpaceInfo.userCell + "\\" + this.itemsInfo.partNo; let alertShown = false; console.log("DirPath? ", dirPath); try { const encodedPath = encodeURIComponent(dirPath); // 用查询参数传递路径 let response = await this.http.get(`api/PDSWorker/CheckDirectoryExistance?path=${encodedPath}`).toPromise(); // 注意API返回的是{ ok: boolean }对象,需要判断response.ok if (response.ok) { docFound = true; this.LoadRootLevel(dirPath); console.log("directory found from response"); } /* My code Continues*/ } catch (error) { console.error("Error checking directory existence general catch:", error); }
2. 若坚持使用路径参数的处理方式
如果必须用路径参数,需要配置ASP.NET Core路由允许匹配包含特殊字符的完整路径:
修改API路由
// 使用*匹配所有剩余路径段 [HttpGet("CheckDirectoryExistance/{*path}")] public ActionResult CheckDirectoryExistance(string path) { try { // 把路径中的/替换回\(如果是共享路径需要) path = path.Replace("/", "\\"); bool directoryExists = Directory.Exists(path); return Ok(new { ok = directoryExists }); } catch(Exception ex) { return NotFound(ex); } }
修改Angular调用代码
try { // 把反斜杠替换为斜杠,避免路由解析问题 const formattedPath = dirPath.replace(/\\/g, "/"); let response = await this.http.get(`api/PDSWorker/CheckDirectoryExistance/${encodeURIComponent(formattedPath)}`).toPromise(); if (response.ok) { docFound = true; this.LoadRootLevel(dirPath); console.log("directory found from response"); } /* My code Continues*/ } catch (error) { console.error("Error checking directory existence general catch:", error); }
注意:这种方式存在安全风险,可能导致路径遍历攻击,务必做好参数校验。
3. 额外排查点
- 确认控制器路由前缀:检查
PDSWorkerController是否带有[Route("api/[controller]")]特性,确保路由前缀正确。 - 验证URL拼写:确认API路径中的
PDSWorker与控制器类名(PDSWorkerController)一致,ASP.NET Core会自动去掉后缀Controller。 - 检查CORS配置:如果前端和API运行在不同端口,确认CORS策略允许该请求。
内容的提问来源于stack exchange,提问作者JoshQ

