OneClutteredMind
OneClutteredMind

Reputation: 459

Out of box VS 2022 SPA React App won't route Web API

I built a VM running Windows 11 and installed VS 2022 to play around with it. I know I can't be the first to run into this problem but I can't seem to find anything on how to get it to work.

I literally create an Out-Of-The-Box ASP.NET Core with React application. I added a new controller

using Microsoft.AspNetCore.Mvc;

namespace Zignificant.WebApp.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class TestController : ControllerBase
    {
        [HttpGet]
        public IActionResult Get()
        {
            return Ok("test");
        }
    }
}

When I launch the application I can easily hit the Weather Controller that is built-in with PostMan. However, when I try to do an HttpGet on the new Test Controller I get this:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <base href="/" />
    <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
    -->
    <link rel="manifest" href="/manifest.json">
    <link rel="shortcut icon" href="/favicon.ico">
    <!--
      Notice the use of  in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>Zignificant.WebApp</title>
</head>

<body>
    <noscript>
        You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
    <script src="/static/js/bundle.js"></script>
    <script src="/static/js/vendors~main.chunk.js"></script>
    <script src="/static/js/main.chunk.js"></script>
</body>

</html>

I tried removing the "api" portion of the route on the Test Controller thinking it was getting in the way but nothing.

This is literally out-of-the-box application template.

Has anyone else seen this issue? Or am I missing something?

Thank in advance for the help!

Update #1: I check the launchSetting.json and noticed the original port or 7008:

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:2817",
      "sslPort": 44302
    }
  },
  "profiles": {
    "Zignificant.WebApp": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:7008;http://localhost:5008",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
      }
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
      }
    }
  }
}

I change the port to the one indicated in the launchSettings.json file and calling the API seems to work in PostMan.

However, that still doesn't help me when trying to fetch the data from the React Application. Doing so provides me a CORS Error.

Still trying to make sense of this... Seems like the proxy port is causing some sort of an issue that I can't figure out. Any help is appreciated.

Update #2 So, apparently you have add any new controllers that you plan to use in your React Application in the setupProxy.js file:

const createProxyMiddleware = require('http-proxy-middleware');
const { env } = require('process');

const target = env.ASPNETCORE_HTTPS_PORT ? `https://localhost:${env.ASPNETCORE_HTTPS_PORT}` :
  env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(';')[0] : 'http://localhost:2817';

const context =  [
  "/weatherforecast",
  "/api/test"
];

module.exports = function(app) {
  const appProxy = createProxyMiddleware(context, {
    target: target,
    secure: false
  });

  app.use(appProxy);
};

I find this a little bit of an overkill to have to do this. However, I am open minded and Microsoft has surprised me in the past with the results with what I thought was an overkill.

I would like to hear from someone the benefits of using this methodology. Thanks again for your help.

Upvotes: 2

Views: 1416

Answers (1)

PixelPaul
PixelPaul

Reputation: 2767

I was struggling with the same problem when adding a controller to the Visual Studio 2022 "out-of-the-box" .NET Core React SPA template. What I did to get it to work was to find the file setupProxy.js, which in the current template is here: ClientApp\src\setupProxy.js. In this file I added the route to the new controller:

const context =  [
    "/weatherforecast",
    "/api/test"
];

And with that simple addition I was able to hit the controller action and get back a valid response. I did not find this documented anywhere, but it worked for me.

Upvotes: 6

Related Questions