0

Error

The page is a layout page (_layout.vbhtml)

-- The error description:

Cannot use a leading .. to exit above the top directory.

-- The source error:

Line 70: WriteLiteral(" rel=""stylesheet""")
Line 71: 
Line 72: WriteAttribute("href", Tuple.Create(" href=""", 534),     Tuple.Create("""", 591) _
Line 73: , Tuple.Create(Tuple.Create("", 541), Tuple.Create(Of System.Object, System.Int32)(Href("~/frameworks/uikit-3.0.0-beta.30/css/uikit.min.css") _
Line 74: , 541), False) _

It work only if I remove all js/css reference, all declared with tilde.

This

<link rel="stylesheet" href="~/frameworks/uikit-3.0.0-beta.30/css/uikit.min.css"/>

or this

<script src="~/frameworks/jquery/jquery-3.2.1.min.js"></script>

doesn't work, but this work:

<script src="/frameworks/jquery/jquery-3.2.1.min.js"></script>

Config

The configuration of my site is a little complicated.

Root
  ├── bin
  ├── some other folders
  ├── folder-of-mydomain-com (sub application)
  │   ├── bin
  │   ├── frameworks
  │   │      └── uikit-3.0.0-beta.30
  │   │             └── css
  │   │                  └── uikit.min.css
  │   ├── some other folders
  │   ├── template
  │   │   ├── style.css
  │   │   ├── _layout.vbhtml
  │   │   └── index.vbhtml
  │   │
  │   ├── global.asax           ***
  |   └── [sub]web.config       **
  |
  └── [root]web.config          *

* The [root]web.config file contain a rewrite-rule like this:

All request from mydomain.com rewrite to folder-of-domain-com

<action type="Rewrite" url="folder-of-mydomain-com/{R:1}" />

** The [sub]web.config file contain:

<rewrite> <rules> <clear/> ...

*** And in the global.asax there is a RewritePath:

If LCase(Request.Url.AbsolutePath) = "/folder-of-mydomain-com/index.html" Then
    newPath = "~/template/index.vbhtml"
End If

So...

The main domain (maindomain.com) that points to the root work !

maindomain.com/folder-of-mydomain-com/index.html

Why mydomain.com/index.html with '~/' give me this error ? Is a problem of the IIS configuration? should refer to the root of the sub-app.


UPDATE

All links with tilde in Razor layout give me this error. This is a simple image:

<img src="~/template/img/img_01.jpg" />

UPDATE 2

Here the whole project (or the main part without useless code).

_layout.vbhtml

<!DOCTYPE html>
<html>
    <head>
        <title>@*@Page.Title*@</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <script src="~/frameworks/jquery/jquery-3.2.1.min.js"></script>
    </head>
    <body>
        @RenderBody()
    </body>
</html>

index.vbhtml

@Code
    PageData("Title") = "My title"
    Layout = "_layout.vbhtml"
End Code

<div>
    <p>My home page</p>
</div>

[root]web.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.web>
        <compilation debug="true" targetFramework="4.5.2" />
        <httpRuntime targetFramework="4.5.2" />
    </system.web>
  <system.webServer>
    <directoryBrowse enabled="false"/>
    <rewrite>
      <rules>
        <clear/>
        <rule name="MyRule" stopProcessing="true">
          <match url="(.*)" ignoreCase="true" />
          <conditions logicalGrouping="MatchAll">
            <add input="{HTTP_HOST}" pattern="^(www\.)?mydomain\.com$" ignoreCase="false" />
          </conditions>
          <action type="Rewrite" url="folder-of-mydomain-com/{R:1}" />
        </rule>
      </rules>
    </rewrite>
    <handlers>
      <add name="HTML Handler" path="*.html" verb="*" type="System.Web.UI.PageHandlerFactory" resourceType="Unspecified"/>
    </handlers>
  </system.webServer>
</configuration>

[sub]web.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.web>
    <compilation strict="false" explicit="true" targetFramework="4.5.2" />
    <httpRuntime targetFramework="4.5.2" />
    <trust level="Full" />
  </system.web>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <system.webServer>
    <rewrite>
      <rules>
        <clear />
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

global.asax (on sub app)

Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)

    If LCase(Request.Url.AbsolutePath) = "/folder-of-mydomain-com/index.html" Then
        HttpContext.Current.RewritePath("~/template/index.vbhtml")
    End If

    If LCase(Request.Url.AbsolutePath) = "/folder-of-mydomain-com/template/index.html" Then
        HttpContext.Current.RewritePath("~/template/index.vbhtml")
    End If

End Sub

Some examples:

These work

maindomain.com/folder-of-mydomain-com/index.html

maindomain.com/folder-of-mydomain-com/template/index.html

maindomain.com/folder-of-mydomain-com/template/index.vbhtml

mydomain.com/template/index.html

mydomain.com/template/index.vbhtml

maindomain.com/folder-of-mydomain-com/template/index.vbhtml

This don't work (with the known error)

mydomain.com/index.html

The solution

https://stackoverflow.com/a/23302191/4031083

From the above answer:

Url Rewrite and Tilde(~)

After upgrading to ASP.NET Razor 3 or ASP.NET MVC 5, the tilde(~) notation may no longer work correctly if you are using URL rewrites. The URL rewrite affects the tilde(~) notation in HTML elements such as <A/>, <SCRIPT/>, <LINK/>, and as a result the tilde no longer maps to the root directory.

For example, if you rewrite requests for asp.net/content to asp.net, the href attribute in <A href="~/content/"/> resolves to /content/content/ instead of /. To suppress this change, you can set the IIS_WasUrlRewritten context to false in each Web Page or in Application_BeginRequest in Global.asax.

The code

Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
        Request.ServerVariables.Remove("IIS_WasUrlRewritten")
End sub
Baro
  • 5,300
  • 2
  • 17
  • 39
  • Is that `` work too? My best guess is the `script` tag doesn't render given relative path due to URL rewriting rule that pointed to other site root than sub-application root directory (better to show entire URL rewrite rules in root/sub-app web.config there). – Tetsuya Yamamoto Sep 20 '17 at 03:08
  • @TetsuyaYamamoto Right now I'm out of office, and I can't check the answer in depth, but one important thing is: mine isn't an MVC application, it's a simple Razor asp.net and Url.Content dosen't exist. Later check your answer, thank you for now. – Baro Sep 20 '17 at 07:40
  • I edited the answer removing unnecessary MVC-related texts (including `UrlHelper.Content` reference). I want to know how your Razor file can be accessed directly without any controller class-action method like MVC does. – Tetsuya Yamamoto Sep 20 '17 at 07:47
  • Additionally, is that project uses ASP.NET Web Pages? I think Web Pages project can also uses Razor view, but with different approach than MVC. Try to include related code in web.config which lead to the error & exception details, which makes the problem clear. – Tetsuya Yamamoto Sep 20 '17 at 08:00

1 Answers1

1

Cannot use a leading .. to exit above the top directory error usually indicates that the request pointed to the folder one level up from the current page, and since your script resources placed on an application sub-folder, this may indicate that the application root actually used the parent folder (maindomain) instead of sub-folder (folder-of-mydomain-com).

The ASP.NET Web Project Paths denotes the usage of tilde (~):

To overcome these disadvantages, ASP.NET includes the Web application root operator (~), which you can use when specifying a path. ASP.NET resolves the ~ operator to the root of the current application. You can use the ~ operator in conjunction with folders to specify a path that is based on the current root.

Hence that it can be summarized as follows:

~/frameworks/jquery/jquery-3.2.1.min.js => refers to application root path - possible directory structure not exist at root level

/frameworks/jquery/jquery-3.2.1.min.js => refers to site root path - this directory structure exist

The actual problem may lies under your current URL rewriting schema inside application root's web.config. The URL rewriting should be used like this example (notice the regex in match element affects the user-submitted URL in browser, and url assigned to absolute path based from entire site root):

<system.webServer>
    <rewrite>
      <rules>
        <clear/>
        <rule name="MyRule" stopProcessing="true">
          <match url="(.*)" ignoreCase="true" />
          <conditions logicalGrouping="MatchAll">
            <add input="{HTTP_HOST}" pattern="^(mydomain\.com|www\.mydomain\.com)$" ignoreCase="false" />
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          </conditions>
          <action type="Rewrite" url="http://maindomain.com/folder-of-mydomain-com/{R:1}" />
        </rule>
      </rules>
    </rewrite>
</system.webServer>

Depending on your need, the Rewrite as given in the example above may be changed to Redirect rule and add redirectType="Temporary" on action element if necessary:

<action type="Redirect" url="http://maindomain.com/folder-of-mydomain-com/{R:1}" redirectType="Temporary" />

You can also see IIS URL Rewrite Module Configuration Reference for further details.

Related issues:

slash(/) vs tilde slash (~/) in style sheet path in asp.net

IIS7 URL Redirection from root to sub directory

Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61
  • The `[root]web.config` with your rule not seems to work... "Te resource cannot be found". – Baro Sep 20 '17 at 13:17
  • @Baro Which resource said to be missing? I edited the sample to let you try both `Rewrite` & `Redirect` rule version. – Tetsuya Yamamoto Sep 20 '17 at 15:00
  • Now, both `Redirect` and `Rewrite` change the url. With the link `mydomain.com/index.html` they both change the url in `maindomain.com/folder-of-mydomain-com/index.html`. What I want is navigate with `mydomain.com` url (`Rewrite` should do this! strange...). Now I try to rewrite it from IIS. – Baro Sep 20 '17 at 16:36
  • Tetsuya, thank you very very much for your time ! I found the answer... https://stackoverflow.com/a/23302191/4031083. The workaround is this:`Request.ServerVariables.Remove("IIS_WasUrlRewritten")` in `global.asax / Application_BeginRequest`. – Baro Sep 20 '17 at 18:36