ASP.NET 5 HTML5历史记录

9
我正在将我的项目升级到ASPNET5。我的应用程序是一个AngularJS Web应用程序,使用HTML5 Url路由(HTML5 History API)。
在我的以前的应用程序中,我使用了URL Rewrite IIS模块,代码如下:
<system.webServer>
  <rewrite>
    <rules>
      <rule name="MainRule" stopProcessing="true">
        <match url=".*" />
        <conditions logicalGrouping="MatchAll">
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          <add input="{REQUEST_URI}" matchType="Pattern" pattern="api/(.*)" negate="true" />
          <add input="{REQUEST_URI}" matchType="Pattern" pattern="signalr/(.*)" negate="true" />
        </conditions>
        <action type="Rewrite" url="Default.cshtml" />
      </rule>
    </rules>
  </rewrite>
<system.webServer>

我意识到我可以移植这个,但我想最小化我的Windows依赖。根据我的阅读,我认为我应该能够使用ASP.NET 5中间件来实现这一点。
我认为代码应该像这样,但我认为我离正确还很远。
app.UseFileServer(new FileServerOptions
{
    EnableDefaultFiles = true,
    EnableDirectoryBrowsing = true
});

app.Use(async (context, next) =>
{
    if (context.Request.Path.HasValue && context.Request.Path.Value.Contains("api"))
    {
        await next();
    }
    else
    {
        var redirect = "http://" + context.Request.Host.Value;// + context.Request.Path.Value;
        context.Response.Redirect(redirect);
    }
});

基本上,我希望路由任何包含/api/signalr的内容。有关在ASPNET5中实现此目标的最佳方法的建议?

是的,你可以通过使用“中间件”来实现这个。 - agua from mars
你能展示一下你如何完成这个任务吗? - amcdnl
GitHub 上有很多 middleware 示例。其中一个是我写的:https://github.com/aguacongas/chatle/tree/dev/src/ChatLe.HttpUtility - agua from mars
3个回答

6

您本来走在正确的轨道上,但我们不想返回重定向,而是希望重写请求路径。以下代码已在ASP.NET5 RC1中工作。

app.UseIISPlatformHandler();

// This stuff should be routed to angular
var angularRoutes = new[] {"/new", "/detail"};

app.Use(async (context, next) =>
{
    // If the request matches one of those paths, change it.
    // This needs to happen before UseDefaultFiles.
    if (context.Request.Path.HasValue &&
        null !=
        angularRoutes.FirstOrDefault(
        (ar) => context.Request.Path.Value.StartsWith(ar, StringComparison.OrdinalIgnoreCase)))
    {
        context.Request.Path = new PathString("/");
    }

    await next();
});

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

这里的一个问题是,您必须将您的 angular 路由特别编码到中间件中(或者放在配置文件中等)。

最初,我尝试创建一个流水线,在调用 UseDefaultFiles() 和 UseStaticFiles() 后,它会检查路径,如果路径不是 /api,则重写它并发送回去(因为除了 /api 以外的任何内容都应该已经被处理完了)。然而,我从未能让它起作用。


为什么要在服务器端保留Angular路由,这太愚蠢了。所有对服务器的API调用都以“api”开头,您可以轻松使用.StartsWith('api',request.Path)来确定是否设置“/”,对吧? - Elisabeth
2
你可以反转逻辑,将后端路由(在你的情况下只有“api”)保存而不是前端路由。在我的情况下,做前者更有意义,因为我们除了“api”之外还有几个后端路由,而前端路由相对较少。无论哪种方式,它都是一样的。您需要重写需要进入Angular的路由。请记住,如果您的ASP.NET应用程序还负责提供文件(html、css等),则还需要考虑这些路径,除了“api”之外。 - Bill

0

我正在使用:

app.UseMvc(routes =>
{
    routes.MapRoute(
        name:"Everything", 
        template:"{*UrlInfo}", 
        defaults:new {controller = "Home", action = "Index"});
}

这将导致所有路由都命中主页索引页面。当我需要路由超出此范围时,我会在此路由之前添加它们,因为这成为了一个捕获所有路由。


-2

为什么不在MVC中使用路由功能?在Startup.cs的Configure方法中,您可以修改以下内容:

        // inside Configure method in Startup.cs
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller}/{action}/{id?}",
                defaults: new { controller = "Home", action = "Index" });

            // Uncomment the following line to add a route for porting Web API 2 controllers.
            // routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}");
        });  

不适用于HTML5历史记录,您需要仅通过路由资产/ API,其他所有内容应返回索引文件。 - amcdnl

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