Getting 404 / 500 errors deploying ASP.NET Core 5.0 Web API

90 Views Asked by At

TL;DR - I'm getting 404 or 500 errors when trying to deploy a ASP.NET Core 5.0 Web API to a server that has one successfully running already.

First - I apologize for the huge post, but I'm trying to be as detailed as I can be - and I've debunked (for me) various solutions I've found that either didn't work or the problem isn't really the same.

If you are able to help me figure this out, it would be greatly appreciated. I've been pulling my hair out over this for the last several days.

Also, upfront, for reasons beyond my control, I have to use 5.0 in this. There is already another ASP.NET Core 5.0 Web API running on the server (which is why I chose 5.0 as well - the other option is .NET 4.72 Framework)

For info, here is my dotnet --info results:

C:\Users\me>dotnet --info

Host (useful for support):
  Version: 5.0.5
  Commit:  2f740adc14

.NET SDKs installed:
  No SDKs were found.

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]

To install additional .NET runtimes or SDKs:
  https://aka.ms/dotnet-download

Here is the relevant code in my .runtimeconfig.json file:

"runtimeOptions": {
    "tfm": "net5.0",
    "framework": {
      "name": "Microsoft.AspNetCore.App",
      "version": "5.0.0"
},

This started out as the basic new Web API that Visual Studio creates when selecting a new project, and choosing ASP.NET Core Web API as the project type. I chose the following options when creating this project:

  • 5.0 as Target Framework (again, I know it's out of support - but that's not pertinent for the time being... I'll happily upgrade this to 6 or 8 when we are told we can use said platform)
  • No Authentication Type (this api is mainly internal and does not actually interact with any data or SQL)
  • Configure for HTTPS is checked
  • Enable OpenAPI support is UNCHECKED (so there is no Swagger stuff removing the main set of links that come up searching this issue).

This is a simple API that on GET returns some json that tells you the API is running, and on POST it generates a pdf based on some body info passed in and an html file on the server.

Here is the controller code:

using classic.api.pdfmaker.Components;
using classic.api.pdfmaker.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;

namespace classic.api.pdfmaker.Controllers 
{
    [ApiController]
    [Route("mailer/[controller]")]
    public class PDFMakerController : ControllerBase 
    {
        private readonly M2PManager _m2p;

        public PDFMakerController(IConfiguration configuration) 
        {
            _m2p = new M2PManager(configuration);
        }

        [HttpGet]
        public JsonResult Get() 
        {
            var result = new M2PResult();
            result.success = "Cannot use GET";
            result.pdfurl = "PDF Not Generated";
            result.message = "API is up and running - but unable to generate a pdf.";

            return new(result);
        }

        [HttpPost]
        public JsonResult Post([FromBody] M2PData data) 
        {
            return new(_m2p.MakeM2PPDF(data));
        }
    }
}

When I run this via IISExpress on my local machine - everything works as expected. The web page comes up, returns the GET json result, and when I use POSTMAN to run a POST with the body info, the PDF is generated to the location I'm expecting.

On deploying to the server - the code files are in folder D:\Sites\Mailer.

The app pool created is No Managed Code (and Enable 32-Bit is set to false - as I've seen other solutions where people said this caused a problem)

I've tried publishing this in several ways, all giving me the same results:

  • Self-Contained & win-x64 - results in a http 404 error

This generates a web.config file that uses

<aspNetCore processPath=".\classic.api.pdfmaker.exe" 

and when I activate app pool, a blank log file is created. When I go to the website (or use Postman for GET()), I get a 404 error. When I stop the app pool, the log file updates and contains the following:

info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: D:\Sites\Mailer
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...

and the Application Event viewer says the application started successfully.

The other application on the server - it's web.config uses processPath="dotnet" arguments=".\classic.api.pdfmaker.dll" and if I change my web.config to that, I get a http 500 error:

A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in 'C:\Program Files\dotnet'. Failed to run as a self-contained app.
The application was run as a self-contained app because 'D:\Sites\Mailer\classic.api.pdfmaker.runtimeconfig.json' did not specify a framework.
If this should be a framework-dependent app, specify the appropriate framework in 'D:\Sites\Mailer\classic.api.pdfmaker.runtimeconfig.json'.

Second attempt was using Framework-Dependent & win-x64.

I basically got the same errors in the same manor, based on how I had the web.config file

Third attempt was Framework-Dependent & Portable

With this method, if I had web.config with processPath="dotnet" arguments=".\classic.api.pdfmaker.dll" OR processPath=".\classic.api.pdfmaker.exe" - I would get the same 404 errors as above, along with the same stdout log (showing the application started and then shutting down when I turn off the app pool).

If my web.config included

<aspNetCore processPath="dotnet" arguments=".\classic.api.pdfmaker.exe"

I get a http 500 error, and the following in the stdout log file:

Error:
An assembly specified in the application dependencies manifest (classic.api.pdfmaker.deps.json) has already been found but with a different file extension:
package: 'classic.api.pdfmaker', version: '1.0.0'
path: 'classic.api.pdfmaker.dll'
previously found assembly: 'D:\Sites\Mailer\classic.api.pdfmaker.exe'

I realize that some of these web.configs are probably bad, and thus causing my errors (at least I'm betting on the 500 errors are from this)... but it doesn't explain my 404 issue.

So I'm hoping someone has run into this and can give me some ideas as to where to go from here.

UPDATE BASED ON QUESTIONS...

First, the URL I'm going to (I do realize I didn't give that) is website.com/mailer/pdfmaker which is the what I set up in the Controller class.

Second, since it was asked - here is program.cs:

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


namespace classic.api.pdfmaker {
    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>();
                });
    }
}

and for added benefit, here is startup.cs:

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

namespace classic.api.pdfmaker {
    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.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.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

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

There are 0 best solutions below