如何在使用ASP.NET友好URL时忽略某些路由?

7
我成功地使用了ASP.NET友好URL,但是我需要忽略特定的Foo.aspx页面的路由(因为这个页面需要POST数据,一旦重新路由,POST数据在Page_Load()中就不再可用了!)。
看起来使用ASP.NET友好URL会舍弃任何忽略路由的尝试。即使在使用ASP.NET友好URL路由后,MSDN示例忽略路由也不起作用。
routes.Ignore("{*allaspx}", new {allaspx=@".*\.aspx(/.*)?"});

那么要忽略对 Foo.aspx 的路由,代码应该像这样,是吗?

routes.Ignore("{*fooaspx}", new { fooaspx = @"(.*/)?foo.aspx(/.*)?" });

Global.asax 代码如下:

public static void RegisterRoutes(RouteCollection routes) {

    // This doesn't work whether I put this code before or after ASP.NET Friendly URLs code.
    routes.Ignore("{*allaspx}", new { allaspx = @".*\.aspx(/.*)?" });

    routes.Canonicalize().Lowercase();

    var settings = new FriendlyUrlSettings();
    settings.AutoRedirectMode = RedirectMode.Permanent;   
    routes.EnableFriendlyUrls(settings);
}

void Application_Start(object sender, EventArgs e) {
   RegisterRoutes(RouteTable.Routes);
}

这个问题曾在ASP.NET Friendly URLs codeplex网站上提出, 但没有得到答案。

感谢您的帮助:)


据我理解,如果存在一个物理文件,则它优先于任何路由配置(over any routing config),那么为什么它会被“重新路由”/重定向? - EdSF
ASP.NET友好的URL代码在所有存在的物理文件(包括site\Foo.aspx)中都能很好地完成重定向工作。例如,url“Site.com\Foo-Bar.aspx”会被重定向到“site.com\foo-bar”,而Foo-Bar.aspx文件是存在的。这如何解释routes.Ignore()不起作用的问题呢? - Patrick from NDepend team
2个回答

12

得益于Damian Edwards的评论,我完全解决了这个问题,感谢Damian。

我只需要从WebFormsFriendlyUrlResolver派生,重写ConvertToFriendlyUrl()方法,使其在url匹配不想重定向的url时变为no-op:

using Microsoft.AspNet.FriendlyUrls.Resolvers;

public class MyWebFormsFriendlyUrlResolver : WebFormsFriendlyUrlResolver {
   public MyWebFormsFriendlyUrlResolver() { }

   public override string ConvertToFriendlyUrl(string path) {
      if (!string.IsNullOrEmpty(path)) {
         if (path.ToLower().Contains("foo")) { // Here the filter code
            return path;
         }
      }
      return base.ConvertToFriendlyUrl(path);
   }
}

然后在 Global.asax 中,代码现在看起来像这样:

public static void RegisterRoutes(RouteCollection routes) {
    routes.Canonicalize().Lowercase();
    var settings = new FriendlyUrlSettings();
    settings.AutoRedirectMode = RedirectMode.Permanent;
    routes.EnableFriendlyUrls(settings, 
                              new IFriendlyUrlResolver[] { 
                                 new MyWebFormsFriendlyUrlResolver() });
}

void Application_Start(object sender, EventArgs e) {
   RegisterRoutes(RouteTable.Routes);
}

3

这很有趣-必须要动手尝试:)在我上面的评论中,我想说的是"不需要忽略”。

我既“对”又“错”。

  • 正确:不需要忽略
  • 错误:不是因为我所说的(关于物理文件),而是通过一开始就没有调用重定向

这将导致失败(将发生重定向,POST数据会丢失):

<asp:Button ID="btn1" runat="server" Text="Go" PostBackUrl="~/Target.aspx" />

这样做很好(您将获得POST数据,不会发生重定向):

 <asp:Button ID="btn1" runat="server" Text="Go" PostBackUrl="~/Target" />

区别?在第二个选项中,我没有要求FriendlyUrls "重新路由"任何内容。对于第一个选项,我要求一个 "aspx" 文件,因此FriendlyUrls将忠实地执行其目的并 "处理" 它(并对 "友好的URL" 进行永久重定向,这是一个GET请求,所有POST数据都会丢失)。

  • 检查第一选项(target.aspx)的请求: target.aspx request
  • 检查第二个选项(无扩展名,target)的请求: enter image description here

这是一个提示:

var settings = new FriendlyUrlSettings();
settings.AutoRedirectMode = RedirectMode.Permanent;   

它实现了它所说的功能,“执行永久重定向”(到“友好的URL”)……当需要时(如果请求了一个“aspx”文件)。您可以在WebForms网站中的任何页面上进行调整。

  • 如果您请求foo.aspx,则会看到一个重定向(到foo
  • 如果您请求foo,则不会有重定向

您还可以将其注释掉。

settings.AutoRedirectMode = RedirectMode.Permanent;

事实上,这样做是有道理的。没有必要在每个请求上“重定向”(性能问题),只有在必要时才需要...

这样做会起到作用,但也有点违背了FriendlyUrls的初衷...

希望对你有所帮助....


谢谢!您的解决方案将是一个很好的“备选方案”。目前,发送回Site.com\Foo.aspx的源代码的url已经硬编码了。我们可以将源url更改为Site.com\Foo,但这将付出代价。为什么route.Ignore()无效?还有其他重定向替代方案吗?我还尝试在Web.config\system.webServer\rewrite\rules中将Foo.aspx重定向到Foo,但POST数据也会丢失。 - Patrick from NDepend team
1
忽略路由不起作用,因为我们的重定向逻辑发生在HTTP模块中,而不是路由本身。这样我们就可以处理默认文档(例如Default.aspx)的重定向。至于忽略特定路径,如果您从WebFormsFriendlyUrlResolver派生并自定义它,并覆盖一些方法,使它们在路径匹配所需忽略的内容时成为无操作,则很可能可以实现。然后将一个实例传递给接受IFriendlyUrlResolver作为参数的EnableFriendlyUrls的重载。 - Damian Edwards

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