调用部署时找不到 404 ASP.Net 核心 Web API

404 Not Found when Calling Deployed ASP.Net Core Web API

我们费了好大劲才搞清楚为什么我们的 Web API 端点无法在生产环境(Azure Web 应用服务)中调用,但在本地 运行 却运行良好。我们在调用部署的 API 端点时得到 404。

可在 Postman 中使用的本地示例 URL: https://localhost:44370/api/Foo/Bar

示例产品 URL 每次 returns 404: https://fooapi.azurewebsites.net/api/Foo/Bar

(brevity/privacy 替换了真实路线)。

我们没有 web.config 文件,也没有 appsettings.json 在本地或部署的构建中。

ProgramStartup 是样板文件,以默认 Web API 模板为蓝本。

Program.cs:

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace FooAPI
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }


        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

Startup.cs:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace FooAPI
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddApplicationInsightsTelemetry();

            services.AddControllers();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHsts();

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

FooController.cs:

using Microsoft.AspNetCore.Mvc;
using FooAPI.Models;
using System.Net;
using System.Threading.Tasks;
using System.IO;
using System.Text;
using System;

namespace FooAPI.Controllers
{
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class FooController : ControllerBase
    {

        public async Task<ActionResult> Bar()
        {
           return new OkObjectResult("Not our real implementation obv.");
        }

    }
}

项目文件:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.18.0" />
    <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
  </ItemGroup>


</Project>

我们已经:

大声笑,我们需要一个 web.config 文件。将我们工作开发部署中的一个复制到项目的根文件夹中(或者您可以在 VS 中添加项目并添加 Web 配置文件)。显然这个文件 不是 可选的,即使你在 VS 中创建一个新的 Web API 项目时默认情况下没有得到一个。

此外,我们通过 Azure DevOps 进行部署,而不是通过在 VS 中右键单击发布,我猜这会在远程部署中为您创建该文件。

这是有道理的——这一定是告诉服务在哪里可以找到您的代码的文件。

示例web.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\FooAPI.dll" stdoutLogEnabled="false" stdoutLogFile="\?\%home%\LogFiles\stdout" hostingModel="InProcess" />
    </system.webServer>
  </location>
</configuration>