14

クライアントに HTTP 403 エラー コードをスローしようとしています。私は HttpException がこれを達成するための最もクリーンな方法であることを読みましたが、それは私にとってはうまくいきません。次のようなページ内から例外をスローします。

throw new HttpException(403,"You must be logged in to access this resource.");

ただし、CustomErrors がオフの場合、これは標準の ASP.Net スタック トレース (500 エラーあり) のみを提供します。CustomErrors がオンの場合、403 エラーが発生したときに表示されるように設定したページにリダイレクトされません。HttpException を忘れて、代わりにすべての HTTP コードを自分で設定する必要がありますか? これを修正するにはどうすればよいですか?

私の Web.Config のカスタム エラー部分は次のとおりです。

<customErrors mode="On" defaultRedirect="GenericErrorPage.html">
      <error statusCode="403" redirect="Forbidden.html" />
</customErrors>

Forbidden.html を取得する代わりに、GenericErrorPage.html を取得します。

4

3 に答える 3

8

次のようにアプリケーション エラーをオーバーライドする必要があります。

    protected void Application_Error()
    {
        var exception = Server.GetLastError();
        var httpException = exception as HttpException;
        Response.Clear();
        Server.ClearError();
        
        var routeData = new RouteData();
        routeData.Values["controller"] = "Errors";
        routeData.Values["action"] = "General";
        routeData.Values["exception"] = exception;
        Response.StatusCode = 500;

        if (httpException != null)
        {
            Response.StatusCode = httpException.GetHttpCode();
            switch (Response.StatusCode)
            {
                case 403:
                    routeData.Values["action"] = "Http403";
                    break;
                case 404:
                    routeData.Values["action"] = "Http404";
                    break;
            }
        }

        IController errorsController = new ErrorsController();
        var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
        errorsController.Execute(rc);
    }

次に、errorsController を追加する必要があります。

public class ErrorsController : Controller
{
    public ActionResult General(Exception exception)
    {
        ViewBag.ErrorCode = Response.StatusCode;
        ViewBag.Message = "Error Happened";

        //you should log your exception here

        return View("Index");
    }

    public ActionResult Http404()
    {
        ViewBag.ErrorCode = Response.StatusCode;
        ViewBag.Message = "Not Found";
        return View("Index");
    }

    public ActionResult Http403()
    {
        ViewBag.Message = Response.StatusCode;
        ViewBag.Message = "Forbidden";
        return View("Index");
    }

}

最後に、errorsController のビューを作成します。Views/Errors/ に index というビューを 1 つだけ作成しました。

于 2011-05-04T13:26:57.817 に答える
3

このコードを Web.config ファイルの要素configuration/system.web に含めます

  <customErrors mode="On">
    <error statusCode="403" redirect="~/errors/Forbidden.aspx"/>
  </customErrors>

期待どおりに動作するように管理しました。

ここで、例を含む優れたチュートリアルを見つけることができます (例 3 が正しいものです): http://aspnetresources.com/articles/CustomErrorPages

または、Response.Status を使用してそうすることができます: Asp Classic は、特定の http ステータス コードを返します。

于 2011-04-10T16:04:55.397 に答える
1

私は実際に、この問題を解決するために自分の気の利いた小さなクラスを作成することになりました。すべてを処理できるわけではなく、MVC で適切に機能するかどうかはわかりませんが、私の用途では機能します。基本的に、ASP.Net を使用して正しいエラー ページとエラー コードを出力するのではなく、エラーをクリアしてからサーバー側の転送を行い、適切な Web.Config エラー ページを表示します。また、customErrors モードを認識し、それに応じて反応します。

public static class CustomErrorsFixer
{
    static public void HandleErrors(HttpContext Context)
    {
        if(RunIt(Context)==false){
            return;
        }
        HttpException ex = Context.Error as HttpException;
        if(ex==null){
            try{
                ex=Context.Error.InnerException as HttpException;
            }catch{
                ex=null;
            }
        }

        if (ex != null){
            Context.Response.StatusCode = ex.GetHttpCode();
        }else{
            Context.Response.StatusCode = 500;
        }
        Context.ClearError();

        Context.Server.Transfer(GetCustomError(Context.Response.StatusCode.ToString()));
        HttpContext.Current.Response.End();
    }
    static protected string GetCustomError(string code)
    {
        CustomErrorsSection section = ConfigurationManager.GetSection("system.web/customErrors") as CustomErrorsSection;

        if (section != null)
        {
            CustomError page = section.Errors[code];

            if (page != null)
            {
                return page.Redirect;
            }
        }
        return section.DefaultRedirect;
    }
    static protected bool RunIt(HttpContext context){
        CustomErrorsSection section = ConfigurationManager.GetSection("system.web/customErrors") as CustomErrorsSection;
        switch(section.Mode){
            case CustomErrorsMode.Off:
                return false;
            case CustomErrorsMode.On:
                return true;
            case CustomErrorsMode.RemoteOnly:
                return !(context.Request.UserHostAddress=="127.0.0.1");
            default:
                return true;
        }
    }

}

そしてそれをアクティブにするには、Global.asax に小さなものを追加するだけです

    protected virtual void Application_Error (Object sender, EventArgs e)
    {
        CustomErrorsFixer.HandleErrors(Context);
    }
于 2011-04-10T20:23:33.503 に答える