System.Cats.Lol
System.Cats.Lol

Reputation: 1770

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

We're having a devil of a time figuring out why our Web API endpoint can't be called in production (Azure web app service), but works fine running locally. We get 404 when calling our deployed API endpoint.

Sample local URL that works in Postman: https://localhost:44370/api/Foo/Bar

Sample prod URL that returns 404 every time: https://fooapi.azurewebsites.net/api/Foo/Bar

(Real routes replaced for brevity/privacy).

We have no web.config file and no appsettings.json either locally or in the deployed build.

Program and Startup are boilerplate, modeled after the default Web API template.

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 file:

<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>

We have already:

Upvotes: 1

Views: 4661

Answers (1)

System.Cats.Lol
System.Cats.Lol

Reputation: 1770

LOL, we needed a web.config file. Copied the one from our working dev deployment into the project's root folder (or you can do Add Item in VS and add Web Configuration File). Apparently this file is not optional even though you don't get one by default when you create a new Web API project in VS.

Also, we were deploying via Azure DevOps and NOT through right-click publish in VS, which I'm guessing would create that file for you in the remote deployment.

It makes sense--this must be the file that tells the service where to find your code.

Example 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>

Upvotes: 3

Related Questions