O.MeeKoh
O.MeeKoh

Reputation: 2156

What configuration is necessary to serve Angular files from ASP.NET Core web api project when both projects were generated separately?

As stated in the title I have two projects which were generated independent of each other. 1. ASP.NET Core project, was generating using the dotnet new webapi -o TestAPI 2. Angular project, generated using the Angular CLI ng new TestAngularApp

Since the web api project is the back-end for the angular project, I want it to serve my angular app. Based on my research the way ASP.NET Core serves static files is you have to create a wwwroot folder at the root directory of your web api project, and put all of contents produced by the ng build --prod command inside that wwwroot folder.

The next step is where I am un-sure what I must configure next. Thus far in my Startup.cs file in the Configure method I have added

app.UseDefaultFiles(); app.UseStaticFiles();

Now this works as expected when I run the webapi project in debug mode straight from Visual Studio. The problem arises when I want to publish the webapi and locally deploy it to IIS.

I run dotnet publish -c Release command and all of the files get generated in the .../publish directory including the wwwroot directory as expected.

In IIS, I then create an application under the Default Web Site and point it the .../publish directory.

IIS Aplication

At this point I have enabled Failed Request Tracing on the Site level.

When I browse the application, my webapi correctly attempts to serve up the index.html file, but it fails to load any of the required assets.

I have tried adding re-write url rules to both the ThePLeague application AND the 'wwwroot' directory that is located inside of that application but this does not work. I have tested to make sure my url re-write module does in fact work and it does.

My question is, Does my webapi require any additional configuration to successfully serve up Angular files?

Do I need to use the SpaFallbackException, UseSpa, UseSpaStaticFiles or any of the Spa prefix extension methods to get this to work, or should the two methods I already have be enough?

Thank you for any insight you can provide.

UPDATE

After adjusting the base URL as mentioned in the answer, my files were successfully served. My base url was adjusted to <base href="/ThePLeague/">. The problem now however is that when I refresh the page. I receive a 404 error. I have the URL re-write rules sitting in the same directory as the ASP.NET Core webapi and NOT inside the wwwroot folder where all of my static files are. This is because when I enable Failed Request Tracing Rules in IIS, there are no logs generated when having the rules created inside the wwwroot folder.

URL re-write rules:

enter image description here

`<system.webServer>
        <rewrite>
            <rules>
                <rule name="test">
                    <match url=".*" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" />
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" />
                    </conditions>
                    <action type="Rewrite" url="wwwroot/index.html" logRewrittenUrl="true" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>`

Trace logs when I refresh the page:

enter image description here

Upvotes: 3

Views: 4451

Answers (1)

itminus
itminus

Reputation: 25380

The Reason

When I browse the application, my webapi correctly attempts to serve up the index.html file, but it fails to load any of the required assets

The reason is that the default index.html generated by ng new TestAngularApp sets the base as /:

<head>
  <meta charset="utf-8">
  <title>TestAngularApp</title>
  <base href="/">
  ....
</head>

This will make all your assets path relative to /. In other words, the compiled scripts referenced in your dist/index.html is relative to the root path /:

<script type="text/javascript" src="runtime.06daa30a2963fa413676.js"></script>
<script type="text/javascript" src="polyfills.d64817aaf614d4221ef9.js"></script>
<script type="text/javascript" src="main.b4ca252475698e802446.js"></script>

Since you're hosting your angular with the Virtual Path of /ThePLeague, your assets URL should be prefixed with /ThePLeague/:

/ThePLeague/runtime.06daa30a2963fa413676.js
/ThePLeague/polyfills.d64817aaf614d4221ef9.js
/ThePLeague/main.b4ca252475698e802446.js

How to fix

  1. Change the base href to /ThePLeague/:

    <base href="/ThePLeague/">
    

    Note there's a trailing / in the base href.

  2. Restart the ThePLeague when need. It should work now.


Does my webapi require any additional configuration to successfully serve up Angular files?

Do I need to use the SpaFallbackException, UseSpa, UseSpaStaticFiles or any of the Spa prefix extension methods to get this to work, or should the two methods I already have be enough?

Actually, if you don't need a SPA fallback, you don't any other codes except the two app.UseDefaultFiles();app.UseStaticFiles() methods you've added.

You don't even have to change the IIS url rewrite rule.

Upvotes: 3

Related Questions