0

I've been trying to make PathLocation(i.e without ' # ' in the URL) routing angular work with razor views in .NET MVC and have had no luck so far.

AppComponent

// app component
import { Component} from '@angular/core'

        @Component({
            moduleId: module.id,
            selector: 'app-root',
            templateUrl: '/Harness2.0/Main/app',// -> MVC controller 
            styleUrls: ['app.component.css']
        })

AppHeader TS

// app-header.ts
import { Component } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'app-header-demo',
    templateUrl: '/Harness2.0/Component/AppHeader',
})

Angular Routing Module:

const appRoutes: Routes = [
    { path: 'appheader-test', component: AppHeaderTestComponent },  
    { path: '', redirectTo: '/', pathMatch: 'full' },

];

Index.cshtml

@{
    ViewBag.Title = "Harness 2.0";
}
<!DOCTYPE html>
<html>
<head>
    <base href="./" />
    <title>@ViewBag.Title</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Load styles -->
    @Styles.Render("~/Content/css")
    @Styles.Render("~/Content/material")
    <!-- Load libraries & Configure SystemJS -->
    @Scripts.Render("~/scripts/ng")
    <script>
        System.import('src').catch(function (err) {
            console.error(err);
        });
    </script>
</head>
<body>
    <app-root>Loading app-root...</app-root>
</body>
</html>

RouteConfig.cs

routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional, }
            );

routes.MapRoute(
                name: "NotFound",
                url: "{*catchall}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

HomeController.cs

public class HomeController : Controller
    {

        public ActionResult Index()
        {
            return View();
        }
    }

MainController.cs

public class MainController : Controller
    {

        public ActionResult App()
        {
            return View();
        }
    }

ComponentsController.cs

public class ComponentController : Controller
    {

        public ActionResult AppHeader()
        {
            return View();
        }
    }

When the application fist loads the URL is http://localhost/Harness2.0/ & the MVC rotuer defaults to HomeController & Index.cshtml is loaded where <app-root> is present.When I navigate to http://localhost/Harness2.0/app-header the components view is loaded & on browser refresh(F5) I get Not found 404 which makes sense as the entire URL goes over to the server & there's no Controller action associated with that particular URL.

One solution I tried was IIS URL Rewrite

<rewrite>
      <rules>
        <rule name="Rewrite URL" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="./" />
        </rule>
      </rules>
    </rewrite>

This renders the Index on refresh but instead of bootstrapping the AppModule it directly enters the app.component.ts where I have some console logs in the constructor which run infinitely until call stack size exceeds.

Any help in this would be much appreciated.

P.S:

I have tried the hash location strategy by using useHash property in RouterModule & everything works fine with it. But I've to make it work with PathLocation which I haven't been able to so far.Also I'm not using .NET Core.

Other related links:

  1. http://knightcodes.com/angular2/2017/01/04/angular-2-routes-with-asp-net-mvc.html
  2. ASP.NET 5 + Angular 2 routing (template page not REloading)

2 Answers 2

1

Kal93, if you're using angular, you needn't use routerConfig.cs. Your page it's always the same (index.cshtml). e.g. in my .NET Core 2.0 I have

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");

        routes.MapSpaFallbackRoute(
            name: "spa-fallback",
            defaults: new { controller = "Home", action = "Index" });
    });

Is Angular who manage the router

Sign up to request clarification or add additional context in comments.

5 Comments

Is there an alternative for app.UseMvc in just .NET .
@kal93 that is a .net core style of making mvc project in a web project. .NET full framework works in a different manner than that. You need to add the routes and then register these routes in global.asax file.
@inthevortex By register I assume you mean this? :RouteConfig.RegisterRoutes(RouteTable.Routes);
@kal93 yes this is the way.
@kal93 I hope the answer below can help you out.
0

I have also tried it in a different manner than Eliseo. This is the Configure method of my Startup class.

Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.Use(async (context, next) => {
                await next();
                if (context.Response.StatusCode == 404 &&
                    !Path.HasExtension(context.Request.Path.Value) &&
                    !context.Request.Path.Value.StartsWith("/api/"))
                {
                    context.Request.Path = "/index.html";
                    await next();
                }
            });

            app.UseMvcWithDefaultRoute();

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

launchSettings.json

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:49600/",
      "sslPort": 0
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "AngularCoreDemo": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "http://localhost:5000/"
    }
  }
}

You will also have to add a proxy class so that the /api requests are routed to localhost:5000 (.net core app) and the other requests are routed to localhost:4200 (angular app).

proxy.config.json

{
  "/api": {
    "target": "http://localhost:5000",
    "secure":  false
  }
}

You need to build your angular app so that the static files rest in wwwroot folder and need to start the server from command line giving the proxy file as argument (please look up the exact syntax).

7 Comments

Correct me if I'm wrong but your answer seems to be referring to Net Core. Will this work in. NET? I appreciate your help.
Yes, this refers to .net core. If you .net application isn't already in development, you can consider using .net core as it is more decoupled compared to .net framework. This is a way to couple .net core MVC/API app with an angular app.
You can follow this tutorial along with it's subsequent ones to combine your angular and .net461 app together. But this uses some old things, like systemjs.config instead of webpack, etc. Hope you like this solution if you want to strictly go for .net461
Thanks. I've seen it before but it doesn't use razor views. Uses just inline html in TS files.
@kal93 you can use inline html inside ts file or you can write a separate html file and give that path in the ts file. That's basically how angular works. The tutorial did that for the simplicity of things. If you need help in building your angular app, read the tutorial here. This will help you out.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.