Search code examples
razorasp.net-routingasp.net-webpages

How can I disable URL routing in ASP.Net WebPages?


Or, if that's impossible for some reason, a simpler question: how can I get the physical directory of the current file from a layout page?

this.VirtualPath will refer to the virtual path of the layout file itself, and this.NormalizePath(".") will only get the virtual path of the directory containing the layout file.

I just want to be able to have a site that doesn't have the possibility of relative links suddenly not working just because some guy typed http://example.com/index/some/other/junk for no reason.

EDIT to show you what I mean:

TestLayout.cshtml

<html>
   <head>
      <title>Test Page</title>
   </head>
   <body>
      <div style="background: grey">
         @Request.RawUrl<br />
         @Request.Url.AbsolutePath<br />
         @Request.Url.AbsoluteUri<br />
         @Request.Url.LocalPath<br />
         @Request.CurrentExecutionFilePath<br />
         @Request.FilePath<br />
         @Request.Path<br />
         @VirtualPath<br />
      </div>
      <div style="background: red">
         @RenderBody()
      </div>
   </body>
</html>

Test.cshtml

@{
   Layout = "TestLayout.cshtml";
}
@Request.RawUrl<br />
@Request.Url.AbsolutePath<br />
@Request.Url.AbsoluteUri<br />
@Request.Url.LocalPath<br />
@Request.CurrentExecutionFilePath<br />
@Request.FilePath<br />
@Request.Path<br />
@VirtualPath<br />

If you go to http://example.com/Test/random/junk/at/the/end, you'll find that the only lines that correctly trim all the cruft are the two @VirtualPath lines - however, the VirtualPath property of the layout page is TestLayout.cshtml. How do I access Test.cshtml's VirtualPath property from within TestLayout.cshtml?


Solution

  • So, after many, many hours, I've figured it out.

    No, you cannot disable the automatic URL routing of ASP.Net WebPages - it's baked in to the WebPageRoute class. The only way to disable it is to disable WebPages entirely.

    There are two ways that you can access the VirtualPath of the parent .cshtml file from a child layout.

    1. You can manually parse the URL. This is fairly involved, although all the work has been done already in the WebPageRoute.cs file, so you can just nick it with a few tweaks. The problem is that you can only get the VirtualPath of the topmost parent page.
    2. You can extend the WebPage class, overriding the ConfigurePage method, and store the argument for later use. Example code follows:

    CustomWebPage.cs

    using System.Web;
    using System.Web.WebPages;
    public abstract class CustomWebPage : WebPage
    {
       private WebPageBase _parentPage;
    
       public WebPageBase ParentPage { get; private set; }
    
       protected override void ConfigurePage(WebPageBase parentPage)
       {
          ParentPage = parentPage;
       }
    }
    

    TestLayout.cshtml

    <html>
       <head>
          <title>Test Page</title>
       </head>
       <body>
          <div style="background: grey">
             Inside the layout page!<br/>
             VirtualPath is: @VirtualPath<br />
             Parent's VirtualPath is: @ParentPage.VirtualPath
          </div>
          <div style="background: red">
             @RenderBody()
          </div>
       </body>
    </html>
    

    Test.cshtml

    @{
        Layout = "TestLayout.cshtml";
    }
    Inside the main test page!<br />
    VirtualPath is @VirtualPath
    

    Output:

    Inside the layout page!

    VirtualPath is: ~/TestLayout.cshtml

    Parent's VirtualPath is: ~/Test.cshtml

    Inside the main test page!

    VirtualPath is ~/Test.cshtml