ASPNET Core ContentRoot로 인한 500 오류 문제

FGPRJS·2023년 1월 5일
0

문제사항

  • Develop환경은 Windows고 Release환경은 Linux이다보니 BasePath/ContentRoot를 찾는데에 문제가 발생하였다.

  • 그 중 릴리즈 환경(Release/Linux)에서 500 에러(Failed to load resource : the server responded with a status of 500())가 발생하며 index.html을 가져올 수 없는 문제.

오류 사항은 대강 다음과 같았다.

dotnet[{secret}]: System.InvalidOperationException: No file provider has been configured to process...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.VirtualFileResultExecutor.GetFileInfor...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.VirtualFileResultExecutor.ExecuteAsync...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.VirtualFileResult.ExecuteResultAsync(ActionContext co...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultAsync(IAct...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFi...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeNextResultFilter...
dotnet[{secret}]: --- End of stack trace from previous location where exception was thrown ---     ...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecuted...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFi...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters() ...
dotnet[{secret}]: --- End of stack trace from previous location where exception was thrown ---     ...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineA...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaite...
dotnet[{secret}]: at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_...
dotnet[{secret}]: at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)    ...
dotnet[{secret}]: at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)    ...
dotnet[{secret}]: at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext ...
dotnet[{secret}]: at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContex...
dotnet[{secret}]: at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessReq...

주요사항은

System.InvalidOperationException: No file provider has been configured to process the supplied file.

이며, 제공된 파일을 처리할 File Provider가 없다는 이야기를 한다.

감사하게도, 문제를 파악하기 쉽게 이하와 같이 구동시에 Content root path를 보여준다.

info: Microsoft.Hosting.Lifetime[0]
dotnet[{secret}]: Now listening on: {secret}
dotnet[{secret}]: info: Microsoft.Hosting.Lifetime[0]
dotnet[{secret}]: Application started. Press Ctrl+C to shut down.
dotnet[{secret}]: info: Microsoft.Hosting.Lifetime[0]
dotnet[{secret}]: Hosting environment: Production
dotnet[{secret}]: info: Microsoft.Hosting.Lifetime[0]
dotnet[{secret}]: Content root path: /

문제 원인

상기 로그에 기재된 Content root path가 최상단 루트인 /이다.

Content root path가 최상위 폴더라서, wwwroot에 있는 webpage를 가져올 수 없었던 것이다.

문제 해결

wwwroot를 static한 content폴더로 사용하고 있다면, Main문이 포함된 Program.csCreateHostBuilder 함수를 다음과 같은 방식으로 설정하여 Content Root를 수정할 수 있다.

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

2차 문제

상기와 같이 작성하게 되면 Windows/Development 환경에서도 Release(publish)폴더를 참조한다.

그래서 이번엔 Dev환경에서 500 오류를 발생

다음과 같이 수정하였다.

public static IHostBuilder CreateHostBuilder(string[] args){
            var coreEnv = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
            var isRelease = coreEnv != Environments.Development;

            var builder = Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    if (isRelease)
                    {
                        webBuilder.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory);
                    }
                    webBuilder.UseStartup<Startup>();
                });

            return builder;
        }
  • CreateHostBuilder에서 Dev환경 여부를 체크해 거기서 Release일때에만 UseContentRoot를 사용했다.

기타 시행착오

  • StartupConfigure에서 env.ContentRootPath를 수정하는 것은 별 도움이 되지 않았다.
profile
FGPRJS

0개의 댓글