使Angular路由在ASP.NET Core 2.0应用程序中运行

时间:2017-12-02 02:37:50

标签: angular iis asp.net-core asp.net-core-2.0

我有一个ASP.NET Core 2.0应用程序,我有Angular 5应用程序。这些是单独开发的(VS2017中的第1个,VS代码中的第2个)。所以我在VSTS中设置CD / CI,并在构建期间将Angular应用程序注入到ASP.NET Core应用程序的/ angularapp /文件夹中。

为了在用户打开http://domain/angularapp时使角度应用程序工作,我在IIS中设置了URL重写规则(所以当它命中/ angularapp时,它会被重写为/angularapp/index.html)。

但是Angular应用程序中的更深层链接呢?如果我尝试打开/ angularapp /功能,我会从ASP.NET Core 2.0中收到404错误。我可以解决这个问题吗?

4 个答案:

答案 0 :(得分:3)

Janne-Harju是对的。解决方案就在这里 - https://code.msdn.microsoft.com/How-to-fix-the-routing-225ac90f。但为了使它工作,请确保你有这个:

    public class CustomTreeViewItem : TreeViewItem
    {
        public String SystemName { get; set; }
        public String Type { get; set; }
        public String ParentItem { get; set; }
        public String Path { get; set; }
    }

    public List<CustomTreeViewItem> treeList = new List<CustomTreeViewItem>();

    public void SetRootNode()
    {
        int itmNumber = datSet.Rows.Count;

        for (int i = 0; i < itmNumber; i++)
        {
            treeList.Add(new CustomTreeViewItem
            {
                SystemName = (string)datSet.Rows[i].ItemArray[1].ToString(),
                Type = (string)datSet.Rows[i].ItemArray[2].ToString(),
                ParentItem = (string)datSet.Rows[i].ItemArray[3].ToString(),
                Path = (string)datSet.Rows[i].ItemArray[4].ToString(),
            });
            treeList[i].Header = treeList[i].SystemName;
        }


        foreach (CustomTreeViewItem item in treeList.Where(treeList => treeList.ParentItem == ""))
        {
            treeView.Items.Add(item);
        }

        foreach (CustomTreeViewItem item in treeList.Where(treeList => treeList.ParentItem != "").Where(treeList => treeList.Type != "Signal"))
        {
            var test = treeList.Find(treeList => treeList.SystemName == item.ParentItem);
            test.Items.Add(item);
        }

    }

答案 1 :(得分:2)

如果您正在寻找一种解决方案,使您的api在同一条路线上,例如&#34; / API /&#34 ;.其他一切都应该被送回SPA,那么这应该适合你。

app.UseWhen(x => !x.Request.Path.Value.StartsWith("/api"), builder =>
{
    builder.Use(async (context, next) =>
        {
            await next();
            if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value))
            {
                context.Request.Path = "/index.html";
                await next();
            }
        })
        .UseDefaultFiles(new DefaultFilesOptions {DefaultFileNames = new List<string> {"index.html"}})
        .UseStaticFiles()
        .UseMvc();
});
app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

答案 2 :(得分:1)

如果您的控制器返回index.html,则此处给出的答案将部分起作用,但还会将请求路由到404 (not found)。我正在使用以下代码:

app.Use(async (context, next) =>
        {
            await next();

            if (!Path.HasExtension(context.Request.Path.Value) &&
                !context.Request.Path.Value.StartsWith("/api/"))
            {
                context.Request.Path = "/index.html";
                await next();
            }
        });

app.UseDefaultFiles(new DefaultFilesOptions { DefaultFileNames = new List<string> { "index.html" }});

这会将所有请求路由到index.html,具有扩展名和api路由的请求除外。请注意,api位是硬编码的,如果更改资源路径,它将停止工作。

答案 3 :(得分:0)

我不确定.net核心2.0,但这适用于.net核心1.1 https://github.com/JanneHarju/MultiSourcePlayList/blob/076c6e4108cbae3bb5128e7f176ed35a61593922/Startup.cs#L169

    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();
            }
        });

在我的回购中还有其他的,如果是角度路线的一部分,但我认为不再有它(或者可能永远不会)。