Angular 使用 Razor 视图和 .NET MVC5
Angular with Razor views & .NET MVC5
我一直在尝试使 PathLocation(即 URL 中没有“#”)路由 angular 与 .NET MVC 中的 razor 视图一起工作,但到目前为止运气不佳。
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路由模块:
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();
}
}
当应用程序第一次加载时,URL 是 http://localhost/Harness2.0/
& MVC rotuer 默认为 HomeController & Index.cshtml 被加载,其中 <app-root>
是 present.When 我导航到 http://localhost/Harness2.0/app-header
组件视图已加载并在浏览器刷新 (F5) 时出现 Not found 404,这很有意义,因为整个 URL 转到服务器并且没有与该特定 URL.[= 关联的控制器操作26=]
我试过的一个解决方案是 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>
这会在刷新时呈现索引,但它不会引导 AppModule,而是直接进入 app.component.ts
,其中我在构造函数中有一些控制台日志,运行 无限直到调用堆栈大小超过。
如有任何帮助,我们将不胜感激。
P.S:
我已经通过在 RouterModule 中使用 useHash 属性 尝试了散列定位策略,并且一切正常。但是我必须让它与我无法做到的 PathLocation 一起工作,所以 far.Also 我没有使用 .NET Core。
其他相关链接:
Kal93,如果您使用的是angular,则无需使用routerConfig.cs。你的页面总是一样的 (index.cshtml)。例如在我的 .NET Core 2.0 中我有
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
是Angular谁管理路由器
我也尝试过与 Eliseo 不同的方式。这是我的Startup
class的Configure
方法。
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/"
}
}
}
您还必须添加代理 class,以便 /api 请求被路由到 localhost:5000(.net 核心应用程序),其他请求被路由到 localhost:4200(angular 应用程序)。
proxy.config.json
{
"/api": {
"target": "http://localhost:5000",
"secure": false
}
}
您需要构建 angular 应用程序,以便静态文件位于 wwwroot
文件夹中,并且需要从命令行启动服务器,将代理文件作为参数(请查找确切的语法)。
我一直在尝试使 PathLocation(即 URL 中没有“#”)路由 angular 与 .NET MVC 中的 razor 视图一起工作,但到目前为止运气不佳。
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路由模块:
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();
}
}
当应用程序第一次加载时,URL 是 http://localhost/Harness2.0/
& MVC rotuer 默认为 HomeController & Index.cshtml 被加载,其中 <app-root>
是 present.When 我导航到 http://localhost/Harness2.0/app-header
组件视图已加载并在浏览器刷新 (F5) 时出现 Not found 404,这很有意义,因为整个 URL 转到服务器并且没有与该特定 URL.[= 关联的控制器操作26=]
我试过的一个解决方案是 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>
这会在刷新时呈现索引,但它不会引导 AppModule,而是直接进入 app.component.ts
,其中我在构造函数中有一些控制台日志,运行 无限直到调用堆栈大小超过。
如有任何帮助,我们将不胜感激。
P.S:
我已经通过在 RouterModule 中使用 useHash 属性 尝试了散列定位策略,并且一切正常。但是我必须让它与我无法做到的 PathLocation 一起工作,所以 far.Also 我没有使用 .NET Core。
其他相关链接:
Kal93,如果您使用的是angular,则无需使用routerConfig.cs。你的页面总是一样的 (index.cshtml)。例如在我的 .NET Core 2.0 中我有
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
是Angular谁管理路由器
我也尝试过与 Eliseo 不同的方式。这是我的Startup
class的Configure
方法。
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/"
}
}
}
您还必须添加代理 class,以便 /api 请求被路由到 localhost:5000(.net 核心应用程序),其他请求被路由到 localhost:4200(angular 应用程序)。
proxy.config.json
{
"/api": {
"target": "http://localhost:5000",
"secure": false
}
}
您需要构建 angular 应用程序,以便静态文件位于 wwwroot
文件夹中,并且需要从命令行启动服务器,将代理文件作为参数(请查找确切的语法)。