ASP.NET Core API - 在 Azure 应用服务上获取 404,但在 Localhost 上工作正常
Posted
技术标签:
【中文标题】ASP.NET Core API - 在 Azure 应用服务上获取 404,但在 Localhost 上工作正常【英文标题】:ASP.NET Core API - Get 404 on Azure App Service, but works ok on Localhost 【发布时间】:2019-09-03 15:37:23 【问题描述】:我有一个托管在 Azure 应用服务中的 ASP.NET Core 2.1 应用。在本地执行时,我可以访问控制器。但是,当我在 Azure 应用中托管时,我会收到 404。这是重现的最少步骤。
在 Visual Studio 2017 中添加一个新项目。选择 ASP.NET Core Web 应用程序。选择 ASP.NET Core 2.1,API 项目模板,无身份验证,配置为 HTTPS。将新应用程序作为自托管(不使用 IIS)运行。浏览到 https://localhost:5001/api/values。我得到了预期的响应(尽管命令行上有一个关于身份验证 HTTPS 连接失败的异常)。
右键单击项目并选择发布。选择以创建新的应用服务。我选择了我现有的订阅、托管计划和资源组。我留下了默认的应用程序名称。创建应用程序。
浏览到网址https://app_name.azurewebsites.net,我看到了默认页面。浏览到https://appname.azurewebsites.net/api/values,我得到一个 404。
我确定我错过了一些非常愚蠢的东西,但我就是想不通。
【问题讨论】:
没有更多数据很难判断。您是否启用了诊断或 Application Insights,以便共享更多信息? 是的,应用洞察已启用。 无法重现您的步骤,能否提供更多详细信息? 我已按照上面列出的步骤进行操作,并再次复制了它。我确保创建一个新的托管计划和资源组。我不知道还能做什么。 【参考方案1】:我能够重现该错误,并且以下解决方案对我有用。如果您之前没有尝试过,请尝试此操作。
-
确保在将应用发布到 Azure 之前将配置设置为发布模式。
在 ValuesController 的 GET 方法之上添加 [Route("/")] 属性,如下所示。
[Route("/")]
[HttpGet("id")]
public ActionResult<string> Get(int id)
return "value";
基本上,任何没有路由属性的控制器方法都使用基于约定的路由。
当您使用 [Route] 属性时,您定义了属性路由,因此常规路由不用于该操作/控制器。
作为一个选项,您可以使用属性路由可以与继承相结合的事实。在整个控制器上设置一个 Route 属性,这将用作路由前缀(与 WebApi 中的 [RoutePrefix] 属性相同):
[Route("api/[controller]")]
public class ValuesController: ControllerBase
【讨论】:
感谢您的帮助。这突然开始起作用了。我多次遵循完全相同的步骤,现在它正在工作。很奇怪。 糟糕,我忘了提到我已将 Visual Studio 2017 从 15.9.10 升级到 15.9.11。 我将 [Route("/")] 放在 Get 操作中,但这是唯一有效的操作 它很奇怪..它不适用于某些应用服务,但是当部署到其他应用服务时,它可以工作..这个错误还有其他需要考虑的事情吗? :(【参考方案2】:不同行为的一个可能原因是标准
if (env.IsDevelopment())
在Startup.cs -> Configure()
中的分支,这将根据ASPNETCORE_ENVIRONMENT
或DOTNET_ENVIRONMENT
环境变量的值而改变。 These will default to production
在我的例子中,我完全删除了 Home
控制器,但无意中将 app.UseExceptionHandler
中间件留在了 Startup.Configure
中指向默认的 Home/Error
。
所以当我的应用部署到 Azure 时,发生了一个我在本地测试期间没有收到的异常(例如 SQL 防火墙 IP 阻塞问题),这意味着任何重定向到错误页面都会导致 404。
if (env.IsDevelopment())
... << Local environment (ASPNETCORE_ENVIRONMENT = 'Development')
else
app.UseExceptionHandler("/Home/Error"); << Watch for this
...
【讨论】:
这让我走上了正轨。原来我的整个 Swagger 配置都在“if (env.IsDevelopment())”括号内。我不知道我在设置应用程序时是否注意力不集中,或者我是否使用了奇怪的模板,但我很高兴这是问题所在。只有一个 404 并且没有任何错误消息,我开始失去信心。但一如既往,它在我身上...... 继续我的上一条评论。 Visual Studio 中的“ASP.NET Core Web Api”模板(至少我使用的那个)在 if(env.IsDevelopment()) 条件中将其添加为默认值。然而,现在我的头脑更清晰了,我可以很容易地看到将我们的 API 文档只公开给我们的开发人员而不是整个世界的好处:-D 模板并不奇怪,你只需放置 app.UseSwagger()和 app.UseSwaggerUI() 正确,基于你想要实现的目标。【参考方案3】:与@StuartLC 的回答类似,Visual Studio 的 .NET Core Web API 模板还有另一个仅用于开发的选项:
当我在浏览器中导航到一个新部署的 Azure WebApp 时,我愚蠢地期待一个新部署的 Azure WebApp 向我显示我的 API 的 Swagger 页面,这让我非常沮丧。相反,我只是得到一个 404。我应该做的是使用 Postman 或其他任何东西来检查。
只有当我检查代码时,我才意识到 Swagger UI 仅在开发时默认连接到模板中:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApplication6 v1"));
【讨论】:
以上是关于ASP.NET Core API - 在 Azure 应用服务上获取 404,但在 Localhost 上工作正常的主要内容,如果未能解决你的问题,请参考以下文章
匿名端点重定向到安全 ASP.Net Core Web 应用程序中的登录屏幕
[Asp.Net Core]ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了
将文件从 ASP.NET Core Web api 发布到另一个 ASP.NET Core Web api