ASP.NET Core RC2中的URL重写

10
我该如何在ASP.NET Core RC2中实现URL重写?当我刷新页面时,从RC1迁移到RC2时,我的Angular 2路由出了问题。
以前我在wwwroot目录下的web.config中使用类似这样的规则。但是在RC2中,我甚至不确定是否应该在我的wwwroot中拥有一个web.config,或者是否只需在项目的根目录中拥有一个web.config即可。
这是我的基本web.config。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" forwardWindowsAuthToken="true" stdoutLogEnabled="true" />
  </system.webServer>
</configuration>

这是我的 wwwroot web.config 文件

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <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" />
            <add input="{REQUEST_URI}" matchType="Pattern" pattern="^/account/" negate="true" />
          </conditions>
          <action type="Rewrite" url="/index.html" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

当我刷新angular 2的路由时,从ASP.NET得到状态码:404;未找到

3个回答

4

我在这里找到了一个可行的解决方案

以下是我的Configure方法中的代码,可以解决我的问题。但是要小心,声明顺序很重要。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));

    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 = "/";
            context.Response.StatusCode = 200;
            await next();
        }
    });

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

    app.UseMvc(routes => {
        routes.MapRoute("Default", "api/{controller}/{action}/{id?}");
    });
}

这是我用来解决完全相同问题的答案。它有一个优点,即满足OP希望使用最少量的.NET代码的要求,而在被接受的答案中并没有找到。 - Gustyn

1
我发现Steve Sanderson提供的解决方案似乎有效。他编写了一个RouteBuilder扩展程序。您可以通过调用扩展方法MapSpaFallbackRoute在Setup.cs中进行配置。

https://github.com/aspnet/JavaScriptServices

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

这是我刚刚想到的解决方案,非常棒。你所需要做的就是安装这个包...在我的情况下,我只需要添加MapSpaFallbackRoute,在我的主页Index Controller中,我只需要返回File("index.html", "text/html"),一切都运行得很好。谢谢! - twilliams
你必须添加控制器才能使其工作吗?我来自Java/Node世界,对MS世界还很陌生,但我尽量让我的项目保持干净。即不涉及任何.Net特定内容。 - Bulan

0

我曾经遇到过完全相同的问题。实际上,对于我来说,当在web.config文件中包含重写规则时,IIS Express服务器甚至没有启动。鉴于此,我四处寻找其他方法来完成相同的事情,而不依赖于重写规则。我发现您可以在startup.cs文件中使用MapWhen函数将任何未被MVC处理的内容发送回index.html。

以下代码已添加到Startup.cs类的Configure方法中,在app.UseMvc()调用之后。

        app.UseMvc();

        // this serves "index.html" from the wwwroot folder when 
        // a route not containing a file extension is not handled by MVC.
        app.MapWhen(context =>
        {
            var path = context.Request.Path.Value.ToLower();
            return path.Contains(".");
        },
            branch =>
            {
                branch.Use((context, next) =>
                {
                    context.Request.Path = new PathString("/index.html");
                    return next();
                });

                branch.UseStaticFiles();
            });

到目前为止,这看起来像是在工作,但我需要做更多的测试来查看是否有任何副作用。个人认为重写规则似乎是一个更好的解决方案,但这似乎可以让我克服这个问题。


这个处理程序允许其他MIME类型或API调用通过吗?我们在同一服务器上有区域设置和API的JSON... - droidalmatter
当使用上下文调用map的第一部分时,您可以决定哪些调用转到MVC,哪些转到静态文件处理程序。因此,您可以明确地将仅API调用路由到服务器,并将其他所有内容发送回您的Angular(或其他)应用程序。在我的特定情况下,我们仅将包含“/api/”路径的任何路径发送到MVC。 - G. Zidar
发现这个中间件代码很有用。我们在Asp.net core 1 RC1项目中使用了类似的东西。需要将其移植到RC2/RTM... https://github.com/BrainCrumbz/AWATTS/tree/master/src/WebPackAngular2TypeScript/Routing - droidalmatter

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