【问题标题】:Is it possible to use a Relative path when setting a custom error page in IIS7?在 IIS7 中设置自定义错误页面时是否可以使用相对路径?
【发布时间】:2011-06-09 16:36:54
【问题描述】:

我正在尝试为我的 Web 应用程序设置自定义 404 错误页面。问题是这个应用程序将被部署到许多不同的环境中。有时它会在虚拟目录中,有时则不会。

我在名为 ErrorPages 的目录中有错误页面,并且我的配置设置如下:

   <httpErrors errorMode="Custom" existingResponse="Replace">
     <remove statusCode="404"/>
     <error statusCode="404" path="/VirtualDir/ErrorPages/404.aspx" responseMode="ExecuteURL" />
   </httpErrors>
</system.webServer>

问题是当我将它部署到网站的根目录时,需要删除 /VirtualDir 部分。如果我在部署之前将其删除,那么我需要在部署到虚拟目录时将其重新添加。有什么方法可以将路径设置为相对于虚拟目录而不是网站?

我尝试过使用~,但这也不起作用,如下所示:

   <httpErrors errorMode="Custom" existingResponse="Replace">
     <remove statusCode="404"/>
     <error statusCode="404" path="~/ErrorPages/404.aspx" responseMode="ExecuteURL" />
   </httpErrors>
</system.webServer>

【问题讨论】:

  • 看来简短的回答是:不,在 IIS7 中设置自定义错误页面时,不能使用相对路径!
  • 马丁,我相信你,但你有引文吗?
  • @Michael This link 声明 URL 应该是服务器相对 URL,而不是使用 responseMode="ExecuteURL" 时的应用程序相对 URL。

标签: asp.net iis-7 custom-error-handling


【解决方案1】:

您可以使用 web.config 转换来设置每个环境的路径:

web.config

<httpErrors errorMode="Custom" existingResponse="Replace">
  <remove statusCode="404"/>
  <error statusCode="404" path="/VirtualDir/ErrorPages/404.aspx" responseMode="ExecuteURL" />
</httpErrors>

web.Release.config

<httpErrors>
  <error statusCode="404" path="/ErrorPages/404.aspx" responseMode="ExecuteURL" />
</httpErrors>

【讨论】:

    【解决方案2】:

    我遇到了类似的问题,所以我使用服务器端代码通过动态生成的 URL(有或没有虚拟目录)重定向到 CustomError 页面,尽管 ~/ 成功地从这里重定向到正确的路径。

    当应用程序发生错误时 Application_Error 触发并最终触发此代码块:

    if (App.Configuration.DebugMode == DebugModes.ApplicationErrorMessage)
    {                    
        string stockMessage = App.Configuration.ApplicationErrorMessage;
    
        // Handle some stock errors that may require special error pages
        HttpException httpException = serverException as HttpException;
        if (httpException != null)
        {
            int HttpCode = httpException.GetHttpCode();
            Server.ClearError();
    
            if (HttpCode == 404) // Page Not Found 
            {
                Response.StatusCode = 404;
                Response.Redirect("~/ErrorPage.aspx"); // ~ works fine no matter site is in Virtual Directory or Web Site
                return;
            }
        }
    
        Response.TrySkipIisCustomErrors = true;
        Response.StatusCode = 404;
        HttpContext.Current.ApplicationInstance.CompleteRequest();
    }
    

    您可以创建一个应用设置并在那里保存路径,而不是在 web.config 的 httpErrors 部分中编写页面路径。在后面的代码中,您可以从应用设置和重定向中获取路径,如上所述。

    我找到了另一个类似的链接,他解释得比我好,所以就去看看吧 http://labs.episerver.com/en/Blogs/Ted-Nyberg/Dates/112276/2/Programmatically-configure-customErrors-redirects/

    【讨论】:

      【解决方案3】:

      让我分享我的解决方案。

      web.config

        <system.webServer>
            <httpErrors errorMode="Custom" existingResponse="Replace">
                <!-- we can't refer virtual path here, so these are absolute paths -->
                <!-- see the additional route "Prefix/GeneralError/{action}" -->
         
                <!-- not found -->
                <remove statusCode="404" />
                <error  statusCode="404" path="/Prefix/GeneralError/New?status=404" responseMode="ExecuteURL"/>
            
                <!-- internal server error -->
                <remove statusCode="500" />
                <error  statusCode="500" path="/Prefix/GeneralError/New?status=500" responseMode="ExecuteURL"/>
         
                <!-- add more codes if needed -->
            </httpErrors>
        </system.webServer>
      

      控制器

      public class GeneralErrorController : Controller
      {
          public ActionResult New()
          {
              return View("ErrorNew");
          }
      }
      

      “ErrorNew.cshtml”剃须刀视图的示例代码

      @{
          int statusCode = Convert.ToInt32(Request.QueryString["status"]);
          string statusText = ((HttpStatusCode)statusCode).ToString();
      
          Layout = null;
          Response.StatusCode = statusCode;
      }
      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="utf-8" />
          <title>Some Title</title>
          <base href="@Url.Content("~")">
          <link href="@Url.Content("~/images/favicon.ico")" rel="icon" type="image/x-icon">
          <link href="@Url.Content("~/css/style.css")" rel="stylesheet">
      </head>
      <body>
          <div>
              <h3>@statusCode</h3>
              <h5>@statusText</h5>
          </div>
      </body>
      </html>
      

      附加路线

      routes.MapRoute(
          // because we need to handle errors for both hosting options
          // "host.com" and "host.com/Prefix"
          "Error page",
          "Prefix/GeneralError/{action}",
          new { controller = "GeneralError" }
      );
      

      这个允许忽略 api 请求

        <location path="api">
            <!-- virtual path ("/api/" or "/Prefix/api/")-->
            <!-- we shouldn't override api errors with custom html error page -->
            <!-- see https://stackoverflow.com/a/25555786/985457 -->
            <system.webServer>
                <httpErrors errorMode="Custom" existingResponse="PassThrough" >
                  <clear/>
                </httpErrors>
            </system.webServer>
        </location>
      

      【讨论】:

        猜你喜欢
        • 2011-06-13
        • 1970-01-01
        • 2012-02-09
        • 1970-01-01
        • 1970-01-01
        • 2016-05-26
        • 2010-10-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多