ASP.NET Core中资源的相对URL在从开发环境到生产环境时不起作用

5

我在我的ASP.NET Core和Angular 2应用程序中遇到了一个问题,它在开发过程中表现得非常好,但是当发布到IIS并为ASP.NET Core正确配置时,它无法加载所需的样式表和脚本。

我通过返回VirtualFileResult将所有不映射到我的API路由的请求重定向回index.html。 index.html具有

<!DOCTYPE html>
<html>
<head>
    <title>Data Platform</title>
    <meta name="description" content="Data Platform" />
    <meta charset="utf8" />

    <base href="/" />
    <link rel="stylesheet" href="lib/css/vendors.css" />
    <link rel="stylesheet" href="platform/content/css/base.css" />
    <link rel="stylesheet" href="platform/content/css/bootstrap-overrides.css" />
    <link rel="shortcut icon" type="image/x-icon" href="favicon.ico" />

    <script src="lib/vendors.js"></script>
    <script>
        System.config({
            packages: {
                "/platform/": { defaultExtension: "js" }
            }
        });

        System.import("/platform/boot");
    </script>
</head>
<body>
    <data-platform>Initializing...</data-platform>
</body>
</html>

Startup.cs 配置非常基础:

app.UseIISPlatformHandler();

if (string.Equals(env.EnvironmentName, "Development", StringComparison.OrdinalIgnoreCase))
{
    app.UseDeveloperExceptionPage();
}

app.UseFileServer(false);
app.UseStatusCodePages();
app.UseMvc(routeBuilder =>
{
    routeBuilder.MapRoute(
        name: "Api",
        template: "api/{controller}/"
    );
    routeBuilder.MapRoute(
        name: "Client Passthrough",
        template: "{*any}",
        defaults: new { Controller = "ClientPassthrough", Action = "Index" }
    );
});

ClientPassthrough控制器操作非常基本:

public IActionResult Index()
{
    return new VirtualFileResult("~/index.html", "text/html");
}

在开发环境中运行良好,在生产环境中失败。我已经尝试将基本 href 更改为 ~/,这将指向正确的应用程序根目录而不是服务器根目录的后续 url... 但它仍然无法在 /wwwroot/ 文件夹中找到那些 css 文件或脚本。


当你说找不到那些CSS文件时:如果index.html被正确请求,你应该在例如Chrome开发者网络中看到所有的CSS文件请求,并在那里获得更多线索。 - vinjenzo
在Chrome中按F12并检查“网络”选项卡,这将告诉您它正在尝试从哪里加载文件,并为您提供有关问题的线索。 - Langley
当您部署到IIS时,您是使用子应用程序还是根站点?https://github.com/aspnet/IISIntegration/issues/14 - Tratcher
1
你真的需要客户端透传吗?如果你配置了以下内容却无法正常工作:app.UseDefaultFiles(); app.UseStaticFiles(); - vinjenzo
@vinjenzo 我之所以这么做是因为我似乎无法获取完整的客户端路径,以便让Angular 2路由进行处理。DefaultFiles()只会在URL中给出应用程序根目录。如果您知道更好的方法,请告诉我!Tratcher 我会检查一下的。我想我之前看过那个页面,但却陷入了早期的帖子而不是后来的帖子。我会检查一下并更新是否有效。 - Cowman
显示剩余2条评论
2个回答

3

如果您正在使用带有Razor的.NET Core,您可以添加以下代码来将基本URL设置为您发布到的IIS应用程序的URL。

<base href="@(Url.Content("~"))" />

这段代码应该放在 <title> 元素的下方,在 <head> 中。

然后,当您引用根时,请使用

<link rel="stylesheet" href="lib/css/vendors.css" />

在路径前面没有斜杠的情况下。这是对我有效的方法。

如果您尝试使用<base href="/" /><base href="~/" />,IIS将不知道该怎么做,因为波浪符除非被.NET解析,否则就没有意义,而不是作为页面中的文本提供。

希望这能帮助到某些人。


0

我的方法是使用URL重写,也许在这个post中你可以得到更多的提示,如果你想尝试的话:

<rewrite>
  <rules>
    <!--Redirect selected traffic to index -->
    <rule name="Index Rule" stopProcessing="true">
      <match url=".*" />
      <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_URI}" matchType="Pattern" pattern="^/api/" negate="true" />
      </conditions>
      <action type="Rewrite" url="/index.html" />
    </rule>
  </rules>
</rewrite>

一起,在 Startup.cs 文件中:

 app.UseDefaultFiles();

 app.UseStaticFiles();

在mvc配置中不再有客户端,我猜...

我不明白为什么需要返回完整路径,如果它已经在客户端终端点调用时可用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接