如何修复我的路由?我有一个带有 Angular 前端的 C# 项目。如果我转到调用 Angular 组件的 c# View ,一切都会中断。如果我调用 Angular View (直接从 URL),一切正常。
C# 路由到 C# View
xxx/Home/index 这只是一个调用 Angular 组件的 View (它会抛出一堆 500 错误)手动路由到 Angular
/anything 添加到 url (xxx/Home/Index/anything),Angular 路由将接管一切并正常加载。索引方法调用
public class HomeController : Controller
{
public IActionResult Index()
{
return View("IndexAng");
}
}
IndexAng.cshtml
@{
ViewData["Title"] = "Home Page";
}
@*<script src="https://npmcdn.com/tether@1.2.4/dist/js/tether.min.js"></script>*@
@*<app asp-prerender-module="ClientApp/dist/main-server">Loading...</app>*@
<h3>Loading Ang App root:</h3>
<app-root></app-root>
<script src="~/dist/vendor.js" asp-append-version="true"></script>
@section scripts {
<script src="~/dist/main-client.js" asp-append-version="true"></script>
}
从Startup.cs配置方法
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ApplicationDbContext identityContext,
UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager)
{
#if DEBUG
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true
});
}
else
{
app.UseExceptionHandler("/Home/Error");
}
#else
app.UseExceptionHandler("/Home/Error");
#endif
app.UseStaticFiles();
//app.UseSession();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
}
尝试导航到 main-client.js 的屏幕截图
最佳答案
首先,注意一点:我遇到了完全相同的问题,但使用的是 ASP.NET MVC 5。 因此,我不能 100% 保证完全相同的解决方案会奏效。
但是,我相当确定我要描述的技术是可靠的,并且 至少可以通过最小的努力进行调整。
归根结底:为了拥有ASP.NET MVC(简称MVC) 和 Angular 2+ 愉快地共存,他们必须知道路由处理在哪里 服务器的责任将结束,而客户端的责任将开始。
我们还必须了解 MVC 如何在提供路由时简化地址 请求。
我提倡的解决方案是创建一个 Controller ,称为 NgController ,
它将为所有单页应用程序(从现在开始,SPA)提供服务
您的安装。
NgController 的草图这是:
public class NgController : Controller
{
private boolean Authenticated()
{
// returns true if the user is authenticated. This system can
// (and probably should) be integrated or replaced with
// one of the ASP.NET Core authentication modules.
return true;
}
public ActionResult Index()
{
if (!Authenticated())
return RedirectToAction("Login", "Authentication", new { ReturnUrl = HttpContext?.Request?.Path });
// Index does not serve directly the app: redirect to default one
return RedirectToAction("TheApp");
}
// One action for each SPA in your installment
public ActionResult TheApp() => UiSinglePageApp("TheApp");
public ActionResult AnotherSPA() => UiSinglePageApp("AnotherSPA");
// The implementation of every SPA action is reusable
private ActionResult UiSinglePageApp(string appName)
{
if (!Authenticated())
return RedirectToAction("Login", "Authentication", new { ReturnUrl = HttpContext?.Request?.Path });
return View("Ui", new SinglePageAppModel { AppName = appName });
}
}
真正基本的东西:我们只需要确保默认 Index操作不直接提供给任何应用程序。
然后,我们需要确保 MVC 路由正常工作:
/TheApp/...和 /AnotherSPA/作为根路由(因为我们喜欢简短的助记 URL)一些路线以及它们应该如何表现:
https://server:port 的 URL应该重定向到 https://server:port/TheApp https://server:port/TheApp应由 TheApp 提供服务NgController 中的操作https://server:port/AnotherSPA应由 AnotherSPA 提供服务NgController 中的操作https://server:port/TheApp/some/token/and/subroute/for/angular/deep/linking应由
TheApp NgController 中的操作以及 TheApp 之后的所有内容应保持原样并直行
到 Angular 路由器我选择的配置是这样的(MVC 5,需要对 MVC Core 2 进行一些调整):
public static void RegisterRoutes(RouteCollection routes)
{
// the Ng controller is published directly onto the root,
// the * before id makes sure that everything after the action name
// is kept as-is
routes.MapRoute("Ng",
"{action}/{*id}",
new {controller = "Ng", id = UrlParameter.Optional},
new {action = GetUiConstraint()}
);
// this route allows the mapping of the default site route
routes.MapRoute(
"Default",
"{controller}/{action}/{*id}",
new { controller = "Ng", action = "Index", id = UrlParameter.Optional }
);
}
/// <summary> The Ui constraint is to be used as a constraint for the Ng route.
/// It is an expression of the form "^(app1)|(app2)$", with one branch for
/// each possible SPA. </summary>
/// <returns></returns>
public static string GetUiConstraint()
{
// If you don't need this level of indirection, just
// swap this function with the result.
// return "^(TheApp)|(AnotherSPA)$";
var uiActions = new ReflectedControllerDescriptor(typeof(NgController))
.GetCanonicalActions()
.Select(x => x.ActionName.ToLowerInvariant())
.Where(x => x != "index")
.Select(x => "(" + x + ")");
return string.Concat("^", string.Join("|", uiActions), "$");
}
现在 MVC 路由和 Controller 可以正常运行,并且可以测试重定向部分 以及“不要乱用应用程序名称后的所有内容”部分。 ;)
我们现在必须设置托管 Angular 应用程序所需的唯一 MVC View 。
“Ng” Controller 需要一个“Ui” View 。唯一真正重要的一点
View 的 <base>标记在 html 文档的头部。
我亲自复制了dist文件夹到 static MVC 站点内的文件夹,
只是为了澄清命名。 “静态”文件夹旨在包含所有
(你猜对了)静态内容。我认为 MVC 创建了一个 Content文件夹,由
默认,但我从来不喜欢那个名字。
MVCroot
|-static
|-ng
|-TheApp (this is the dist folder for TheApp)
|-AnotherSPA (this is the dist folder for AnotherSPA)
我也把每个js文件打包成一个文件,名字和SPA一样,但是没必要。
而且我不喜欢 partials,只是因为我不需要布局,所以我把所有东西放在一起。
YMMV.
Ui.cshtml
@{
Layout = null;
var baseUrl = Url.Content("/") + Model.AppName;
var appName = Model.AppName.ToLowerInvariant();
}
<!DOCTYPE html>
<html style="min-height: 100%;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/x-icon" href="~/static/favicon.ico">
<title>My marvelous application</title>
@Url.CssImportContent("static/ng/{appName}/css/main.css")
<!-- This is the CRUCIAL bit. -->
<base href="@baseUrl">
</head>
<body>
<app-root>Loading...</app-root>
@Url.ScriptImportContent($"~static/ng/{appName}/main.js")
</body>
</html>
AAAAAnd... 我们完成了 MVC 方面的工作。
在客户端,我们只需要确保 Angular 管理路由 使用适当的默认值(不要启用散列选项)。
一切都应该正常工作。
希望对您有所帮助。
关于c# View 调用 Angular 组件中断,但直接调用 Angular 工作正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52449672/
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file