【问题标题】:.NET Core API Endpoint gives 404 only in deployed version.NET Core API Endpoint 仅在已部署版本中提供 404
【发布时间】:2021-11-11 04:35:23
【问题描述】:

我正在构建一个托管在 IIS 中的 .NET Core (3.1) Web API。

我有 2 个端点:

/api/status

/api/widget/config/{id}

两个端点在本地运行时都能完美运行。 /api/status 端点也适用于我部署的版本。但是另一个端点在部署的版本中给出了 404 错误。由于它在本地工作,我认为这是它如何部署的问题。请问您能帮我理解这个问题吗?

这是我的 2 个控制器代码:

[Route("api/[controller]")]
[ApiController]
public class StatusController : ControllerBase
{
    [HttpGet]
    public ActionResult Get()
    {
        return Ok("API is available");
    }
}

[Route("api/[controller]")]
[ApiController]
public class WidgetController : ControllerBase
{
    private readonly IWidgetService service;

    public WidgetController(IWidgetService _service)
    {
        service = _service;
    }

    [HttpGet]
    [Route("~/api/[controller]/[action]/{id}")]
    public ActionResult Config(Guid id)
    {
        return Ok(service.GetWidgetConfig(id));
    }
}

下面是我的 Program.cs 和 Startup.cs:

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();

    using (var scope = host.Services.CreateScope())
    {
        var services = scope.ServiceProvider;
        try
        {
            SeedDatabase.Initialize(services);
        }
        catch (Exception ex)
        {
            var logger = services.GetRequiredService<ILogger<Program>>();
            logger.LogError(ex, "An error occured seeding the DB");
        }
    }

    host.Run();
}

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

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(opts => opts.UseSqlServer(Configuration.GetConnectionString("sqlConnection"),
        options => options.MigrationsAssembly("MyProject")));

    services.AddIdentity<ApplicationUser, IdentityRole>(opt =>
    {
        opt.Password.RequiredLength = 8;
        opt.Password.RequireDigit = true;
        opt.Password.RequireUppercase = true;
        opt.Password.RequireNonAlphanumeric = true;
        opt.SignIn.RequireConfirmedAccount = false;
        opt.SignIn.RequireConfirmedAccount = false;
        opt.SignIn.RequireConfirmedPhoneNumber = false;
    }).AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddScoped<IWidgetService, WidgetService>();

    services.AddCors(o => o.AddPolicy("CorsPolicy", builder => {
        builder
        .WithMethods("GET", "POST")
        .AllowAnyHeader()
        .AllowAnyOrigin();
    }));

    services.AddMvc()
        .AddNewtonsoftJson(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();

    app.UseCors("CorsPolicy");

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

【问题讨论】:

  • 主/错误路由是否有效? app.UseExceptionHandler("/Home/Error");

标签: asp.net-core iis asp.net-core-webapi


【解决方案1】:

将您的控制器代码更改为:

[Route("api/[controller]")]
[ApiController]
public class WidgetController : ControllerBase
{
    private readonly IWidgetService service;

    public WidgetController(IWidgetService _service)
    {
        service = _service;
    }

    [HttpGet("Config/{id}")]
    public ActionResult Config(Guid id)
    {
        return Ok(service.GetWidgetConfig(id));
    }
}

【讨论】:

  • 您能帮我理解一下之前的路线规范有什么问题吗?
  • @MarkSeymour 不是。但正确的代码是我发送的
【解决方案2】:

如下更改您的代码:-

Startup.cs

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

控制器:-

[ApiController]
[Route("api/[controller]")]
public class WidgetController : ControllerBase
{
    private readonly IWidgetService service;

    public WidgetController(IWidgetService _service)
    {
        service = _service;
    }

    [HttpGet("Config/{id}")]
    public ActionResult Config(Guid id)
    {
        return Ok(service.GetWidgetConfig(id));
    }
}

还可以尝试在appsettings.Development.json 文件中写入连接字符串。

它将解决您的问题。

【讨论】:

  • 我的应用程序也在使用传统的 MVC 页面。您对 startup.cs 的建议更改会对此产生影响吗?
  • @MarkSeymour 试试看,让我知道发生了什么。
猜你喜欢
  • 1970-01-01
  • 2020-09-10
  • 1970-01-01
  • 2019-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-10
  • 2017-02-13
相关资源
最近更新 更多