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 -&gt; Configure() 中的分支,这将根据ASPNETCORE_ENVIRONMENTDOTNET_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

ASP.NET Core Web Api 自动帮助页面

将 OpenID Connect 与 .NET Core 3.0 ASP.NET Core API 服务一起使用时出错

ASP.NET Core Web API 在 API GET 请求中检索空白记录