4

I would like to be able to to start an AspNetCore web app from a console application.

when running the web app the static files load fine

enter image description here

I referenced that web app in the console app and added this code, also in the console app:

using System;
using System.Diagnostics;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

namespace SelfHostedConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {

            System.Threading.Tasks.Task.Run(() => ExterrnalLoginTest.Program.Main(null));


            Console.WriteLine("Please enter any key to exit");
            Console.ReadLine();
        }
    }
}

I've also added this to webb app cproj without luck:

<ItemGroup>
    <Content Remove="wwwroot\**" />
</ItemGroup>

<ItemGroup>
    <Content Include="wwwroot\**" CopyToPublishDirectory="PreserveNewest">
    </Content>
</ItemGroup>

This did add wwwroot folder to the console app output but the website static file are still not loading.

enter image description here

boruchsiper
  • 2,016
  • 9
  • 29
  • 53
  • One solution would be to run the web app as a separate process `System.Diagnostics.Process.Start("ExterrnalLoginTest.exe");` – lukaszberwid Sep 01 '20 at 15:44

2 Answers2

4

The issue you are seeing is that when you start the webhost with the other app, it's using the other apps location as it's root. So, here is starting the service normally:

webhost

Here it is starting it with the console application:

console

So what's happening is when you add ExternalLoginTest as a dependency to SelfHostedConsoleApp, the compiler now moves ExternalLoginTest module in to SelfHostedConsoleApp's directory essentially breaking your paths.

Step 1: Copy over wwwroot directory

So the challenge here is that we have to move the wwwroot to the new destination. I see you tried that in your question, but it needs to be like this:

<Project Sdk="Microsoft.NET.Sdk.Web">

    <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>
    </PropertyGroup>

    <ItemGroup>
        <Content Include="wwwroot\**" Link="wwwroot\%(RecursiveDir)%(Filename)%(Extension)"
                         CopyToOutputDirectory="PreserveNewest" />
    </ItemGroup>
</Project>

This is going to create a symbolic link back to the wwwroot directory in the host project.

Step 2: EnableDefaultContentItems option set to false

When you do this, you will see all kinds of errors and something about adding EnableDefaultContentItems to false. So let's go ahead and do that:

<Project Sdk="Microsoft.NET.Sdk.Web">

    <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <EnableDefaultContentItems>false</EnableDefaultContentItems>
    </PropertyGroup>

    <ItemGroup>
        <Content Include="wwwroot\**" Link="wwwroot\%(RecursiveDir)%(Filename)%(Extension)"
                         CopyToOutputDirectory="PreserveNewest" />
    </ItemGroup>
</Project>

If we run it now, it's going to return a 404. But, to prove static content is working, try going to http://localhost:5000/favicon.ico and it will show you the static content.

Step 3: Add your razor pages as Content

The reason why it is now returning 404 is because none of your razor pages are marked as Content so the framework thinks you have no pages to display. The only major drawback to using EnableDefaultContentItems set to false is we have to manually add your razor pages to your .csproj files. Visual Studio won't do it for us any more. So, now your project file will look like this:

<Project Sdk="Microsoft.NET.Sdk.Web">

    <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <EnableDefaultContentItems>false</EnableDefaultContentItems>
    </PropertyGroup>

    <ItemGroup>
        <Content Include="wwwroot\**" Link="wwwroot\%(RecursiveDir)%(Filename)%(Extension)"
                CopyToOutputDirectory="PreserveNewest" />
    </ItemGroup>

    <ItemGroup>
        <Content Include="Pages\Error.cshtml" />
        <Content Include="Pages\Index.cshtml" />
        <Content Include="Pages\Privacy.cshtml" />
        <Content Include="Pages\Shared\_Layout.cshtml" />
        <Content Include="Pages\Shared\_ValidationScriptsPartial.cshtml" />
        <Content Include="Pages\_ViewImports.cshtml" />
        <Content Include="Pages\_ViewStart.cshtml" />
    </ItemGroup>

</Project>

A shortcut to doing this is to shift-click on your pages, right-click and do "properties" then in the property window change Build Action to Content.

Step 4: Run!

At this point we should be 100%: finished

Andy
  • 12,859
  • 5
  • 41
  • 56
0

Every .Net Core application is a console application unless you deploy it to a webserver.

And all Asp.Net Core web applications are console applications which run Kesterl as there web server, unless explicitly told not to.

Still not clear why you would want to do this, but simply run the application with dotnet run on the command line and you'll get a console app running a web server.

Ceemah Four
  • 458
  • 4
  • 11