在 IIS7 中设置自定义错误页面时是否可以使用相对路径?

发布于 2024-11-14 11:08:25 字数 860 浏览 2 评论 0原文

我正在尝试为我的 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>

I'm trying to set a custom 404 error page for my web application. The trouble is that this application will be deployed to a number of different environments. Sometimes it will be in a virtual directory and sometimes it won't.

I have the error page in a directory called ErrorPages and have set up my config like this:

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

The trouble is when I deploy this to the root of a web site, the /VirtualDir part needs to be removed. If I remove it before deployment then I need to add it back in when deploying to a virtual directory. Is there any way I can set the path to be relative to the virtual directory and not to the site?

I have tried using a ~, but that does not work either, like this:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

萤火眠眠 2024-11-21 11:08:25

您可以使用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>

You could use web.config transforms to set the path per environment:

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>
是你 2024-11-21 11:08:25

我遇到了类似的问题,因此我使用服务器端代码使用动态生成的 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/

I was facing similar problem , so I used server side code to redirect to CustomError page with the dynamically generated URL (with or without Virtual Directory) although ~/ successfully redirect to correct path from here.

When an error occurs in the application Application_Error fires and eventually this code block is fired:

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();
}

Instead of writing you page path in httpErrors section of web.config you can create an app setting and save path there. In the code behind you can get the path from app setting and redirect as describe above.

I found another similar link and he explained it better than me so just go though it
http://labs.episerver.com/en/Blogs/Ted-Nyberg/Dates/112276/2/Programmatically-configure-customErrors-redirects/

怪异←思 2024-11-21 11:08:25

让我分享我的解决方案。

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");
    }
}

的示例代码,

@{
    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>

“ErrorNew.cshtml” razor view附加路由

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>

Let me share my solution.

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>

controller

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

Example code for "ErrorNew.cshtml" razor view

@{
    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>

additional route

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" }
);

this one allows to ignore api requests

  <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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文