Skip to content

ASP.NET Core with Angular throws Exception on startup after publish #55687

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 task done
kratofl opened this issue May 13, 2024 · 16 comments
Open
1 task done

ASP.NET Core with Angular throws Exception on startup after publish #55687

kratofl opened this issue May 13, 2024 · 16 comments
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions

Comments

@kratofl
Copy link

kratofl commented May 13, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

When I publish my ASP.NET Core application with angular I get an exception:

Expected Behavior

I should not throw an exception on startup.

Steps To Reproduce

  1. Create and project with the template: "Angular and ASP.NET Core"
    image
  2. Start it once to test
  3. Publish to local folder
    image
  4. Start the .exe file.

Exceptions (if any)

warn: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[16]
The WebRootPath was not found: C:\source\repos\AngularApp1\AngularApp1.Server\bin\Release\net8.0\wwwroot. Static files may be unavailable.
warn: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[16]
The WebRootPath was not found: C:\source\repos\AngularApp1\AngularApp1.Server\bin\Release\net8.0\wwwroot. Static files may be unavailable.
fail: Microsoft.Extensions.Hosting.Internal.Host[11]
Hosting failed to start
System.IO.IOException: Failed to bind to address http://[::]:8080: address already in use.
---> Microsoft.AspNetCore.Connections.AddressInUseException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
---> System.Net.Sockets.SocketException (10048): Only one usage of each socket address (protocol/network address/port) is normally permitted.
at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, Boolean disconnectOnFailure, String callerName)
at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransportOptions.CreateDefaultBoundListenSocket(EndPoint endpoint)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketConnectionListener.Bind()
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketConnectionListener.Bind()
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransportFactory.BindAsync(EndPoint endpoint, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.TransportManager.BindAsync(EndPoint endPoint, ConnectionDelegate connectionDelegate, EndpointConfig endpointConfig, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.<>c__DisplayClass28_01.<<StartAsync>g__OnBind|0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(ListenOptions endpoint, AddressBindContext context, CancellationToken cancellationToken) --- End of inner exception stack trace --- at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(ListenOptions endpoint, AddressBindContext context, CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions.BindAsync(AddressBindContext context, CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.Kestrel.Core.AnyIPListenOptions.BindAsync(AddressBindContext context, CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context, CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(ListenOptions[] listenOptions, AddressBindContext context, Func2 useHttps, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.BindAsync(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.StartAsync[TContext](IHttpApplication1 application, CancellationToken cancellationToken) at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken) at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__15_1(IHostedService service, CancellationToken token) at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List1 exceptions, Func3 operation)
Unhandled exception. System.IO.IOException: Failed to bind to address http://[::]:8080: address already in use.
---> Microsoft.AspNetCore.Connections.AddressInUseException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
---> System.Net.Sockets.SocketException (10048): Only one usage of each socket address (protocol/network address/port) is normally permitted.
at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, Boolean disconnectOnFailure, String callerName)
at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransportOptions.CreateDefaultBoundListenSocket(EndPoint endpoint)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketConnectionListener.Bind()
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketConnectionListener.Bind()
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransportFactory.BindAsync(EndPoint endpoint, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.TransportManager.BindAsync(EndPoint endPoint, ConnectionDelegate connectionDelegate, EndpointConfig endpointConfig, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.<>c__DisplayClass28_01.<<StartAsync>g__OnBind|0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(ListenOptions endpoint, AddressBindContext context, CancellationToken cancellationToken) --- End of inner exception stack trace --- at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(ListenOptions endpoint, AddressBindContext context, CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions.BindAsync(AddressBindContext context, CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.Kestrel.Core.AnyIPListenOptions.BindAsync(AddressBindContext context, CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context, CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(ListenOptions[] listenOptions, AddressBindContext context, Func2 useHttps, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.BindAsync(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.StartAsync[TContext](IHttpApplication1 application, CancellationToken cancellationToken) at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken) at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__15_1(IHostedService service, CancellationToken token) at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List1 exceptions, Func3 operation)
at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
at Program.

$(String[] args) in C:\source\repos\AngularApp1\AngularApp1.Server\Program.cs:line 30

.NET Version

8.0.204

Anything else?

  • Visual Studio 2022 Windows: 17.9.6
  • Node: v20.12.2
  • Angular: 17.3.0
  • I've triple checked it, nothing is running on port 8080 already
@ghost ghost added the area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions label May 13, 2024
@amcasey
Copy link
Member

amcasey commented May 15, 2024

That error appears to say that the port is already in use. You shut down the instance you ran to test the project in step (2) before running another copy in step (4)?

Edit: just noticed the note at the bottom of your report. How are you confirming that 8080 is available?

@amcasey
Copy link
Member

amcasey commented May 15, 2024

@danroth27 Is that template owned by aspnetcore or JavaScript/TypeScript?

@amcasey
Copy link
Member

amcasey commented May 15, 2024

I did my best to follow those repro steps and didn't see that behavior. It wasn't specified, but I assumed it was the AngularApp1.Server project that I should publish to a local folder. I'm a little curious how yours ended up on port 8080 - launchSettings.json appears to specify a random port and running the exe directly appears to default to 5000.

@danroth27
Copy link
Member

@danroth27 Is that template owned by aspnetcore or JavaScript/TypeScript?

This template is owned by @joj's team, but we work pretty closely with them on it.

@kratofl
Copy link
Author

kratofl commented May 16, 2024

I did my best to follow those repro steps and didn't see that behavior. It wasn't specified, but I assumed it was the AngularApp1.Server project that I should publish to a local folder. I'm a little curious how yours ended up on port 8080 - launchSettings.json appears to specify a random port and running the exe directly appears to default to 5000.

Ok. I've sort of "fixed" it.
I forgot that I set the environment variable (ASPNETCORE_URLS), but it was a while ago.

I've removed that entry and now it works. But I'm still curious why it didn't work.

@kratofl
Copy link
Author

kratofl commented May 16, 2024

But theres another issue.
The compiled angular code is put into "wwwroot/browser".
And I cannot access the page.
But when I move the compiled angular files out of the browser folder directly into wwwroot, then it works.
Any idea why?

@amcasey
Copy link
Member

amcasey commented May 16, 2024

But I'm still curious why it didn't work [with ASPNETCORE_URLS].

Presumably, another process was consuming the same environment variable. You could check using something like netstat.

But theres another issue.

Can you please provide new repro steps? Are you using the built app or the published one? How did you try to access the page? What behavior did you see when you failed to access it?

@kratofl
Copy link
Author

kratofl commented May 26, 2024

Sorry for the late response

Can you please provide new repro steps? Are you using the built app or the published one? How did you try to access the page? What behavior did you see when you failed to access it?

I use the published one, the build one works fine with the debugger.
I've tried to access it with "localhost:5000".
It just says that the page isn't working.
But after moving the content from the sub directory to wwwroot directly it works fine.

@amcasey
Copy link
Member

amcasey commented May 30, 2024

I've tried to access it with "localhost:5000".

I'm assuming you mean in a browser, as opposed to curl or HttpClient?

It just says that the page isn't working.

Is it the client or the server saying that? What does the server log show?

@kratofl
Copy link
Author

kratofl commented Jun 9, 2024

I'm assuming you mean in a browser, as opposed to curl or HttpClient?

Yes I used my browser.

Is it the client or the server saying that? What does the server log show?

My browser showed me that.
When my application starts I also get this message:
The WebRootPath was not found: C:\source\repos\AngularApp1\AngularApp1.Server\bin\Release\net8.0\wwwroot. Static files may be unavailable.
It tries to find the compiled angular files in the wwwroot folder directly but they are located in a subfolder browser. Everytime I do a publish, I need to move the files from wwwroot/browser to wwwroot

@amcasey
Copy link
Member

amcasey commented Jun 11, 2024

Sounds like it could be this: dotnet/sdk#6597

Edit: or maybe not quite? It sounds like you're saying the files are published, but in a subfolder?

@joj
Copy link

joj commented Jun 11, 2024

Hi! By default we will take the assets (javascript files and other things you may need to publish) from wwwroot, but you can change that but configuring a property in the Angular project. I believe what you're saying is you want the assets to be in wwwroot/browser? I think this (or something similar to this) should work:

<PropertyGroup>
  <PublishAssetsDirectory>wwwroot/browser</PublishAssetsDirectory>
</PropertyGroup>

That path may need to be rooted, I can't recall right now, so that may work too.

If on the other hand you want to change where angular is putting the files (so wwwroot instead of wwwroot/browser), that's angular configuration that should be in a js file in your project.

@kratofl
Copy link
Author

kratofl commented Jun 26, 2024

If on the other hand you want to change where angular is putting the files (so wwwroot instead of wwwroot/browser), that's angular configuration that should be in a js file in your project.

I want that yes, but I haven't found the configuration for it.
But the main issue about that is that the published project that has been freshly created is not working on the IIS because the angular files are located (by default) in wwwroot/browser and I have to move the files every time to wwwroot in order for it to work.

@kratofl
Copy link
Author

kratofl commented Nov 22, 2024

I've found a workaround.

I've added this configuration to my .csproj file

<Target Name="MoveAngularFiles" AfterTargets="Publish">
  <ItemGroup>
    <AngularFiles Include="$(PublishDir)wwwroot\browser\**\*" />
  </ItemGroup>

  <!-- Move files from wwwroot/browser to wwwroot -->
  <Copy SourceFiles="@(AngularFiles)"
        DestinationFiles="@(AngularFiles->'$(PublishDir)wwwroot\%(RecursiveDir)%(Filename)%(Extension)')"
        SkipUnchangedFiles="true" />

  <!-- Delete wwwroot/browser -->
  <RemoveDir Directories="$(PublishDir)wwwroot\browser" />
</Target>

The reason why I cannot access the web without moving the files from wwwroot/browser to wwwroot is that the IIS is looking for an Index.html file in the wwwroot folder but is not finding any.
But this also applies if I start the .exe manually. It cannot find the browser/index.html since the application is not configured this way.

It's strange that this is an issue when you use the template from ASP.NET Core but no one has addressed it. I've seen another repo which is doing it this way.

@olafurfannsker
Copy link

There are 2 problems that I have seen when creating a new angular asp.net core web application using the Visual Studio template and when I fix them I have no problem publishing to azure either directly or via Github actions.

  1. The template fails to create the wwwroot folder in the server project and I need create that and put an item in there with a content publish property.

  2. There is a wrong version of javascript sdk in the client esproj file

I need to change it to: I would appreciate if you could please fix these things in the near future. With these changes I can happily create and publish new angular asp.net core apps.

I'm using angular 19 and .NET 9 and tailwindcss 4 on

Microsoft Visual Studio Community 2022 (64-bit) - Current. (Both x64 and arm64)
Version 17.13.5

regards
Olafur Gislason

@bjarketrux
Copy link

I created a project from the template today and I can confirm that - when publishing - the wwwroot folder is not added to the output.

.esproj file:

<Project Sdk="Microsoft.VisualStudio.JavaScript.Sdk/1.0.2191419">

If I change the version number to 1.0.2980569 (the latest from here) then the folder is created and the compiled Angular application is added along with the compressed versions.

I did not have to make a wwwroot my self, but it also works if I do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions
Projects
None yet
Development

No branches or pull requests

6 participants