75

古いサイトで、次を追加して CustomErrors の動作方法を変更していましたredirectMode="ResponseRewrite"(3.5 SP1 の新機能):

<customErrors mode="RemoteOnly" defaultRedirect="Error.aspx" redirectMode="ResponseRewrite">
    <error statusCode="404" redirect="404.aspx" />
</customErrors> 

問題は、一般的なエラー ページ ( を設定しない場合に表示されるページ) が表示されることですcustomErrors。その部分を削除すると、正常にredirectMode="ResponseRewrite"動作します。

同じサーバーでホストされている他のサイトでも同じ設定を使用しているため、3.5 SP1 がサーバーにインストールされていると確信しています。

何か案は?

4

10 に答える 10

104

バックグラウンドでResponseRewrite使用する MVC アプリケーションでこれを行おうとする人は注意が必要です。Server.Transferしたがって、defaultRedirectはファイル システム上の正当なファイルに対応している必要があります。どうやらServer.Transferは MVC ルートと互換性がないため、エラー ページがコントローラー アクションによって処理された場合、Server.Transferは /Error/Whatever を探しますが、ファイル システムでは見つからず、一般的な 404 エラー ページを返します!

于 2010-09-22T14:28:44.460 に答える
53

私にとって完全に機能する唯一の方法は、カスタム エラーをオフにして、iis のエラー ページを web.config で置き換えることです。応答とともに正しいステータス コードを送信し、mvc を経由しないという利点があります。

ここにコードがあります

  1. カスタム エラーをオフにする

    <customErrors mode="Off" />
    
  2. エラーページを置き換える

    <httpErrors errorMode="Custom" existingResponse="Replace">
      <remove statusCode="404" subStatusCode="-1" />
      <remove statusCode="500" subStatusCode="-1" />
      <error statusCode="404" path="Error404.html" responseMode="File" />
      <error statusCode="500" path="Error.html" responseMode="File" />
    </httpErrors>
    

ノート。responsemode="file"URL がファイルへの直接リンクである場合に使用します

情報: http://tipila.com/tips/use-custom-error-pages-aspnet-mvc

于 2012-03-11T17:37:42.380 に答える
20

何が起こっているかというと、IIS がエラー ステータス コードを見て、自分のページではなく独自のエラー ページを表示しているということです。解決するには、エラー ページのコード ビハインド ページでこれを設定して、IIS がこれを実行しないようにする必要があります。

Response.TrySkipIisCustomErrors = true;

これは IIS7 以降でのみ機能します。以前のバージョンの IIS では、エラー ページの設定をいじる必要があります。

于 2010-02-16T09:26:07.130 に答える
16

に依存しServer.Transferているため、 の内部実装はResponseRewriteMVC と互換性がないようです。

これは私には明らかな機能の穴のように思えたので、HTTP モジュールを使用してこの機能を再実装することにしました。以下のソリューションでは、通常どおりに有効な MVC ルート (物理ファイルを含む) にリダイレクトすることで、エラーを処理できます。

<customErrors mode="RemoteOnly" redirectMode="ResponseRewrite">
    <error statusCode="404" redirect="404.aspx" />
    <error statusCode="500" redirect="~/MVCErrorPage" />
</customErrors>

これは、次のプラットフォームでテストされています。

  • 統合パイプライン モードの MVC4 (IIS Express 8)
  • クラシック モードの MVC4 (VS 開発サーバー、Cassini)
  • クラシック モードの MVC4 (IIS6)

namespace Foo.Bar.Modules {

    /// <summary>
    /// Enables support for CustomErrors ResponseRewrite mode in MVC.
    /// </summary>
    public class ErrorHandler : IHttpModule {

        private HttpContext HttpContext { get { return HttpContext.Current; } }
        private CustomErrorsSection CustomErrors { get; set; }

        public void Init(HttpApplication application) {
            System.Configuration.Configuration configuration = WebConfigurationManager.OpenWebConfiguration("~");
            CustomErrors = (CustomErrorsSection)configuration.GetSection("system.web/customErrors");

            application.EndRequest += Application_EndRequest;
        }

        protected void Application_EndRequest(object sender, EventArgs e) {

            // only handle rewrite mode, ignore redirect configuration (if it ain't broke don't re-implement it)
            if (CustomErrors.RedirectMode == CustomErrorsRedirectMode.ResponseRewrite && HttpContext.IsCustomErrorEnabled) {

                int statusCode = HttpContext.Response.StatusCode;

                // if this request has thrown an exception then find the real status code
                Exception exception = HttpContext.Error;
                if (exception != null) {
                    // set default error status code for application exceptions
                    statusCode = (int)HttpStatusCode.InternalServerError;
                }

                HttpException httpException = exception as HttpException;
                if (httpException != null) {
                    statusCode = httpException.GetHttpCode();
                }

                if ((HttpStatusCode)statusCode != HttpStatusCode.OK) {

                    Dictionary<int, string> errorPaths = new Dictionary<int, string>();

                    foreach (CustomError error in CustomErrors.Errors) {
                        errorPaths.Add(error.StatusCode, error.Redirect);
                    }

                    // find a custom error path for this status code
                    if (errorPaths.Keys.Contains(statusCode)) {
                        string url = errorPaths[statusCode];

                        // avoid circular redirects
                        if (!HttpContext.Request.Url.AbsolutePath.Equals(VirtualPathUtility.ToAbsolute(url))) {

                            HttpContext.Response.Clear();
                            HttpContext.Response.TrySkipIisCustomErrors = true;

                            HttpContext.Server.ClearError();

                            // do the redirect here
                            if (HttpRuntime.UsingIntegratedPipeline) {
                                HttpContext.Server.TransferRequest(url, true);
                            }
                            else {
                                HttpContext.RewritePath(url, false);

                                IHttpHandler httpHandler = new MvcHttpHandler();
                                httpHandler.ProcessRequest(HttpContext);
                            }

                            // return the original status code to the client
                            // (this won't work in integrated pipleline mode)
                            HttpContext.Response.StatusCode = statusCode;

                        }
                    }

                }

            }

        }

        public void Dispose() {

        }


    }

}

使用法

これを最終的な HTTP モジュールとして web.config に含めます。

  <system.web>
    <httpModules>
      <add name="ErrorHandler" type="Foo.Bar.Modules.ErrorHandler" />
    </httpModules>
  </system.web>

  <!-- IIS7+ -->
  <system.webServer>
    <modules>
      <add name="ErrorHandler" type="Foo.Bar.Modules.ErrorHandler" />
    </modules>
  </system.webServer>
于 2015-03-31T09:18:37.707 に答える
10

この質問が少し古いことは知っていますが、これを機能させるために静的ファイルである必要はないことを指摘する必要があると思いました。

私は同様のことに遭遇しました.Error.aspxでそのエラーを見つけるだけの問題です.私たちの場合、使用中のマスターページがセッションデータの一部に依存しており、ResponseRewriteが設定されているときにセッションが利用できないためです.私たちの Error.aspx ページ。

このセッションが利用できないのは、特定のアプリ構成によるものなのか、ASP.net の「設計による」部分によるものなのかはまだわかりません。

于 2009-08-06T00:43:21.013 に答える
1

クエリを ASP.NET MVC コントローラーに転送するエラー ページを aspx で作成しました。クエリをこの aspx ページに書き直すと、クエリがカスタム コントローラーに転送されます。

protected void Page_Load(object sender, EventArgs e)
{
  //Get status code
  var queryStatusCode = Request.QueryString.Get("code");
  int statusCode;
  if (!int.TryParse(queryStatusCode, out statusCode))
  {
    var lastError = Server.GetLastError();
    HttpException ex = lastError as HttpException;
    statusCode = ex == null ? 500 : ex.GetHttpCode();
  }
  Response.StatusCode = statusCode;

  // Execute a route
  RouteData routeData = new RouteData();
  string controllerName = Request.QueryString.Get("controller") ?? "Errors";
  routeData.Values.Add("controller", controllerName);
  routeData.Values.Add("action", Request.QueryString.Get("action") ?? "Index");

  var requestContext = new RequestContext(new HttpContextWrapper(Context), routeData);
  IController controller = ControllerBuilder.Current.GetControllerFactory().CreateController(requestContext, controllerName);
  controller.Execute(requestContext);
}

詳細については、 https : //stackoverflow.com/a/27354140/143503 をご覧ください。

于 2014-12-08T08:42:09.463 に答える
1

問題は Error.aspx にあることがわかりました。問題の原因となった error.aspx の実際のエラーが何であったかをまだ見つけることができません。

ページを静的な html ファイルに変更すると、問題が解決しました。

于 2009-04-23T17:09:27.880 に答える
0

redirectMode="ResponseRewrite" を使用する場合、web.config ファイルの書き換え領域に何かを追加する必要があることがわかりました。問題は、あなたのサイトが壊れているときです! サイトが書き換えを処理する「virtual.aspx」を呼び出すことができないため、URL の書き換えはできません。

于 2011-03-22T12:06:40.597 に答える
0

私の特定のケースでは、私のエラー ページには、Session を使用しようとしたユーザー コントロールを持つマスター ページがありました。Session を使用できない場合は、HttpException が発生します。最も簡単な修正は、静的 html に切り替えることです。2 番目に簡単な修正は、より単純なエラー ページを使用することです。最も難しい修正は、エラー ページがどこにも仮定を行わないようにすることです (たとえば、Session が例外をスローしないなど)。おそらくエラーになることはありません。

于 2010-08-13T19:04:31.273 に答える