abpframework / abp

Open-source web application framework for ASP.NET Core! Offers an opinionated architecture to build enterprise software solutions with best practices on top of the .NET. Provides the fundamental infrastructure, cross-cutting-concern implementations, startup templates, application modules, UI themes, tooling and documentation.
https://abp.io
GNU Lesser General Public License v3.0
12.98k stars 3.45k forks source link

Volo.Abp.AbpException: Could not find file '/libs/abp/core/abp.css' when trying to load ABP Login Page from Angular UI #18873

Closed zachhongcy closed 7 months ago

zachhongcy commented 10 months ago

Is there an existing issue for this?

Description

Hi ABP team, I have came across an error where the required abp.css could not be found in Azure App Service when I was trying to load ABP Login page from Angular page that is hosted in Azure Static Web Apps. After failing to load the Login page, based on the logs it attempted to load ABP Error page with the same error as well.

Hope that your team will be able to help me resolve this issue, thanks!

Reproduction Steps

As I am setting up a fresh ABP project, there is minimal changes done on ABP generated codes. However these are my setups:

  1. Generate new .NET 8 and angular 17 project using abp cli command: abp new ZachDevAbpTest -u angular --pwa -csf.
  2. Changed my appSettings.json and environment.prod.ts to point to Azure App Services (.NET 8) (url: zachdevabptest-api.azurewebsites.net) and Azure Static Web Apps (angular) (url: https://delightful-water-0dfb19500.4.azurestaticapps.net) respectively. I also changed the default connection string to point to the SQL database that is created in Azure.
  3. Deployed to Azure App Service and Azure Static Web App using github action workflow yml file:
    
    name: Build and deploy ASP.Net Core with Angular app to Azure Web App

on: push: branches:

jobs: build-backend: runs-on: ubuntu-latest

steps:
  - uses: actions/checkout@v2

  - name: Set up .NET Core
    uses: actions/setup-dotnet@v1
    with:
      dotnet-version: '8.x'
      include-prerelease: true

  - name: Install ABP cli
    run: dotnet tool install -g Volo.Abp.Cli

  - name: Install ABP libs
    run: abp install-libs
    working-directory: ./aspnet-core/src/ZachDevAbpTest.HttpApi.Host

  - name: Build with dotnet
    run: dotnet build --configuration Release
    working-directory: ./aspnet-core

  - name: Run migrations
    run: dotnet run -- "${{ secrets.CONNECTION_STRING }}"
    working-directory: ./aspnet-core/src/ZachDevAbpTest.DbMigrator

  - name: dotnet publish apihost
    run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/apihost
    working-directory: ./aspnet-core/src/ZachDevAbpTest.HttpApi.Host

  - name: Generate authserver.pfx
    run: dotnet dev-certs https -v -ep ${{env.DOTNET_ROOT}}/apihost/authserver.pfx -p XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

  - name: Upload artifact for apihost
    uses: actions/upload-artifact@v2
    with:
      name: .net-apihost
      path: ${{env.DOTNET_ROOT}}/apihost

deploy-backend: runs-on: ubuntu-latest needs: build-backend environment: name: 'Production' url: ${{ steps.deploy-to-webapp-1.outputs.webapp-url }}

steps:
  - name: Download artifact from apihost
    uses: actions/download-artifact@v1
    with:
      name: .net-apihost
      path: ./apihost

  - name: Deploy apihost
    id: deploy-to-webapp-1
    uses: azure/webapps-deploy@v2
    with:
      app-name: 'zachdevabptest-api'
      slot-name: 'Production'
      publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE }}
      path: ./apihost

build-deploy-frontend: runs-on: ubuntu-latest needs: deploy-backend name: Build and Deploy Angular App steps:

4. Verified that the deployment was successful:
.NET Core Swagger: ![image](https://github.com/abpframework/abp/assets/149412099/370e5385-347e-4dfd-8837-be8ab8fa3871)
Angular UI: 
![image](https://github.com/abpframework/abp/assets/149412099/c0d89247-cb61-4e91-b512-8976eb5a8407)

5. Verified that abp libs folder is in App Service:
![image](https://github.com/abpframework/abp/assets/149412099/cd29921c-fe3f-41c0-88d6-3aacd23c6b7f)
![Screenshot 2024-01-27 184130](https://github.com/abpframework/abp/assets/149412099/0a7c531b-5f2a-4f15-a987-6f93a891bd23)

6. Click on login from Angular UI
![image](https://github.com/abpframework/abp/assets/149412099/387cd234-51e3-4b6a-a01c-43b2b371964c)

### Expected behavior

ABP Login page should be displayed.

### Actual behavior

App Service logged error: `Volo.Abp.AbpException: Could not find file '/libs/abp/core/abp.css'`, detailed logs:

2024-01-27 10:18:17.364 +00:00 [INF] Executing endpoint '/Account/Login' 2024-01-27 10:18:17.493 +00:00 [INF] Route matched with {page = "/Account/Login", action = "", controller = "", area = ""}. Executing page /Account/Login 2024-01-27 10:18:17.493 +00:00 [INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy 2024-01-27 10:18:18.842 +00:00 [INF] Executing handler method Volo.Abp.Account.Web.Pages.Account.LoginModel.OnGetAsync - ModelState is "Valid" 2024-01-27 10:18:18.881 +00:00 [INF] Executed handler method OnGetAsync, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult. 2024-01-27 10:18:20.039 +00:00 [INF] Bundling bundles/LeptonXLite.Global.990E1D9D56F35BC96DF720644CF93F6F.css (18 files) 2024-01-27 10:18:20.058 +00:00 [INF] Executed page /Account/Login in 2564.7725ms 2024-01-27 10:18:20.058 +00:00 [INF] Executed endpoint '/Account/Login' 2024-01-27 10:18:21.105 +00:00 [ERR] An unhandled exception has occurred while executing the request. Volo.Abp.AbpException: Could not find file '/libs/abp/core/abp.css' at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundlerBase.GetFileInfo(IBundlerContext context, String file) at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundlerBase.GetAndMinifyFileContent(IBundlerContext context, String fileName) at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundlerBase.GetFileContentConsideringMinification(IBundlerContext context, String fileName) at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundlerBase.AddFileToBundle(IBundlerContext context, StringBuilder bundleContentBuilder, String fileName) at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundlerBase.Bundle(IBundlerContext context) at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundleManager.<>cDisplayClass17_0.b0() at System.Collections.Generic.AbpDictionaryExtensions.<>cDisplayClass7_02.<GetOrAdd>b__0(TKey k) at System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func2 valueFactory) at System.Collections.Generic.AbpDictionaryExtensions.GetOrAdd[TKey,TValue](ConcurrentDictionary2 dictionary, TKey key, Func1 factory) at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundleCache.GetOrAdd(String bundleName, Func1 factory) at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundleManager.AddToBundleCache(String bundleName, IBundler bundler, List1 bundleFiles) at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundleManager.GetBundleFilesAsync(BundleConfigurationCollection bundles, String bundleName, IBundler bundler) at Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundleManager.GetStyleBundleFilesAsync(String bundleName) at Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers.AbpTagHelperStyleService.GetBundleFilesAsync(String bundleName) at Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers.AbpTagHelperResourceService.ProcessAsync(ViewContext viewContext, TagHelper tagHelper, TagHelperContext context, TagHelperOutput output, List1 bundleItems, String bundleName) at Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers.AbpBundleTagHelperService2.ProcessAsync(TagHelperContext context, TagHelperOutput output) at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.<RunAsync>g__Awaited|0_0(Task task, TagHelperExecutionContext executionContext, Int32 i, Int32 count) at AspNetCoreGeneratedDocument.Themes_LeptonXLite_Layouts_Account.<>c__DisplayClass20_0.<<ExecuteAsync>b__0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.SetOutputContentAsync() at AspNetCoreGeneratedDocument.Themes_LeptonXLite_Layouts_Account.ExecuteAsync() at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context) at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts) at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderLayoutAsync(ViewContext context, ViewBufferTextWriter bodyWriter) at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context) at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable1 statusCode) at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable`1 statusCode) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.gAwaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|28_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.gAwaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.gAwaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.gLogged|17_1(ResourceInvoker invoker) at Microsoft.AspNetCore.Routing.EndpointMiddleware.gAwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger) at Volo.Abp.AspNetCore.Serilog.AbpSerilogMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b0>d.MoveNext() --- End of stack trace from previous location --- at Volo.Abp.AspNetCore.Auditing.AbpAuditingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Volo.Abp.AspNetCore.Auditing.AbpAuditingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>cDisplayClass2_0.<b0>d.MoveNext() --- End of stack trace from previous location --- at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Volo.Abp.AspNetCore.Security.Claims.AbpDynamicClaimsMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>cDisplayClass2_0.<b0>d.MoveNext() --- End of stack trace from previous location --- at Volo.Abp.AspNetCore.Uow.AbpUnitOfWorkMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>cDisplayClass2_0.<b0>d.MoveNext() --- End of stack trace from previous location --- at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>cDisplayClass2_0.<b0>d.MoveNext() --- End of stack trace from previous location --- at Volo.Abp.AspNetCore.MultiTenancy.MultiTenancyMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>cDisplayClass2_0.<b0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Builder.ApplicationBuilderAbpOpenIddictMiddlewareExtension.<>cDisplayClass0_0.<b0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Volo.Abp.AspNetCore.Tracing.AbpCorrelationIdMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<b0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddlewareImpl.gAwaited|10_0(ExceptionHandlerMiddlewareImpl middleware, HttpContext context, Task task)



### Regression?

_No response_

### Known Workarounds

_No response_

### Version

8.0.2

### User Interface

Angular

### Database Provider

EF Core (Default)

### Tiered or separate authentication server

None (Default)

### Operation System

Linux

### Other information

_No response_
maliming commented 10 months ago

hi

What is the root folder of your API website?

The libs files URL should be:zachdevabptest-api.scm.azurewebsites.net/libs/abp/core/abp.css

image

zachhongcy commented 10 months ago

Hi @maliming

I have not changed the configuration of my App Service so it should be using the default site/wwwroot as the root folder.

Edit: This is the content root path of my website: Content root path: /home/site/wwwroot

Edit 2: I tried move the libs folder manually to both /home/site/ and /home/site/wwwroot/ folders and I get the same error.

maliming commented 10 months ago

The libs files URL should be: xxx.azurewebsites.net/libs/abp/core/abp.css

example: https://abp.io/libs/abp/core/abp.css

image

Can you check this?

zachhongcy commented 10 months ago

Can abp install-libs command installs the required libs files to the correct folder?

I did some testing Login page locally vs on App Service. It seems that the bundle files required for Login page are added when tested locally, but it's not added when tested on App Service.

I tested by requesting Login from aspnet-core swaggare "Authorize" button.

This is the logs to request Login Page when tested locally:

2024-02-01 19:19:54.239 +08:00 [INF] Executing endpoint '/Account/Login'
2024-02-01 19:19:54.247 +08:00 [INF] Route matched with {page = "/Account/Login", action = "", controller = "", area = ""}. Executing page /Account/Login
2024-02-01 19:19:54.248 +08:00 [INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy
2024-02-01 19:19:54.517 +08:00 [INF] Executing handler method Volo.Abp.Account.Web.Pages.Account.LoginModel.OnGetAsync - ModelState is "Valid"
2024-02-01 19:19:54.529 +08:00 [INF] Executed handler method OnGetAsync, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
2024-02-01 19:19:54.664 +08:00 [DBG] Added bundle 'LeptonXLite.Global' to the page in 8.07 ms.
2024-02-01 19:19:54.721 +08:00 [DBG] Added bundle 'LeptonXLite.Global' to the page in 5.32 ms.
2024-02-01 19:19:54.729 +08:00 [DBG] Added bundle 'Volo.Abp.Account.Web.Pages.Account.LoginModel' to the page in 0.50 ms.
2024-02-01 19:19:54.732 +08:00 [INF] Executed page /Account/Login in 484.0971ms
2024-02-01 19:19:54.732 +08:00 [INF] Executed endpoint '/Account/Login'
2024-02-01 19:19:54.734 +08:00 [INF] Request finished HTTP/2 GET https://localhost:44393/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%3Fresponse_type%3Dcode%26client_id%3DZachDevAbpTest_Swagger%26redirect_uri%3Dhttps%253A%252F%252Flocalhost%253A44393%252Fswagger%252Foauth2-redirect.html%26scope%3DZachDevAbpTest%26state%3DVGh1IEZlYiAwMSAyMDI0IDE5OjE5OjUzIEdNVCswODAwIChNYWxheXNpYSBUaW1lKQ%253D%253D - 200 null text/html; charset=utf-8 510.5824ms
2024-02-01 19:19:54.740 +08:00 [INF] Request starting HTTP/2 GET https://localhost:44393/libs/abp/core/abp.css?_v=638379080150560000 - null null
2024-02-01 19:19:54.744 +08:00 [INF] Sending file. Request path: '/libs/abp/core/abp.css'. Physical path: 'C:\Codebase\ZachDevAbpTest\aspnet-core\src\ZachDevAbpTest.HttpApi.Host\wwwroot\libs\abp\core\abp.css'

This is the logs to do the same but in App Service:

2024-02-01T11:48:34.417070642Z: [INFO]  [11:48:34 INF] Executing endpoint '/Account/Login'
2024-02-01T11:48:34.465276911Z: [INFO]  [11:48:34 INF] Route matched with {page = "/Account/Login", action = "", controller = "", area = ""}. Executing page /Account/Login
2024-02-01T11:48:34.465348811Z: [INFO]  [11:48:34 INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy
2024-02-01T11:48:36.049038359Z: [INFO]  [11:48:36 INF] Executing handler method Volo.Abp.Account.Web.Pages.Account.LoginModel.OnGetAsync - ModelState is Valid
2024-02-01T11:48:36.104358069Z: [INFO]  [11:48:36 INF] Executed handler method OnGetAsync, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
2024-02-01T11:48:37.514058351Z: [INFO]  [11:48:37 INF] Bundling __bundles/LeptonXLite.Global.990E1D9D56F35BC96DF720644CF93F6F.css (18 files)
2024-02-01T11:48:37.514109452Z: [INFO]  [11:48:37 DBG] Bundle files:
2024-02-01T11:48:37.536010174Z: [INFO]  [11:48:37 INF] Executed page /Account/Login in 3060.898ms
2024-02-01T11:48:37.536876079Z: [INFO]  [11:48:37 INF] Executed endpoint '/Account/Login'
2024-02-01T11:48:39.054628336Z: [INFO]  [11:48:39 DBG] Added 0 entity changes to the current audit log
2024-02-01T11:48:39.100676893Z: [INFO]  [11:48:39 DBG] Added 0 entity changes to the current audit log
2024-02-01T11:48:39.390623809Z: [INFO]  [11:48:39 ERR] An unhandled exception has occurred while executing the request.
2024-02-01T11:48:39.390663510Z: [INFO]  Volo.Abp.AbpException: Could not find file '/libs/abp/core/abp.css'
maliming commented 10 months ago

Can abp install-libs command installs the required libs files to the correct folder?

This command will restore and copy the js/css to your-web-project/wwwroot/libs.

Check the logs you will see Content root path info:

[13:16:26 INF] Initialized all ABP modules.
[13:16:26 INF] Now listening on: https://localhost:44305
[13:16:26 INF] Application started. Press Ctrl+C to shut down.
[13:16:26 INF] Hosting environment: Development
[13:16:26 INF] Content root path: /aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds
zachhongcy commented 9 months ago

This is my Azure App Service content root path:

2024-01-27 10:16:09.033 +00:00 [INF] Initialized all ABP modules.
2024-01-27 10:16:10.181 +00:00 [INF] Now listening on: http://[::]:8080
2024-01-27 10:16:10.182 +00:00 [INF] Application started. Press Ctrl+C to shut down.
2024-01-27 10:16:10.182 +00:00 [INF] Hosting environment: Production
2024-01-27 10:16:10.182 +00:00 [INF] Content root path: /home/site/wwwroot

Should I change the content root path of ABP app hosted in Application Service? As far as I know this is the default path Azure App Service uses for application hosted in it.

maliming commented 9 months ago

hi

I'm not familiar with Azure.

The libs files URL should be: xxx.azurewebsites.net/libs/abp/core/abp.css

example: https://abp.io/libs/abp/core/abp.css

sagoo33 commented 9 months ago

I had the same issue, but that was because I wasn't running the abp install-libs command. It was working locally, and as a test, I tried a deploy from my local Visual Studio instance instead. This worked, and it published the libs correctly.

This is what my Azure file system looks like: image

I haven't changed any config paths.

zachhongcy commented 8 months ago

@maliming Sorry for the late reply as I was sidetracked by other stuffs. I am able to see ABP's login page after deploying to the root content folder instead of creating a subfolder /apihost as instructed in https://docs.abp.io/en/commercial/latest/startup-templates/application/azure-deployment/step3-deployment-github-action?UI=NG&DB=EF&Tiered=No

maliming commented 8 months ago

hi @zachhongcy

Is your problem solved?

zachhongcy commented 7 months ago

Hi @maliming Yes it's solved now, thanks for the help!