문제

내 응용 프로그램에 맞는 사용자 정의 오류 페이지가 있습니다.

<customErrors mode="On" defaultRedirect="~/errors/GeneralError.aspx"
/>

Global.asax에서 Application_error ()에서 다음 코드는 예외 세부 사항을 얻기 위해 작동합니다.

  Exception ex = Server.GetLastError();
  if (ex != null)
    {
        if (ex.GetBaseException() != null)
            ex = ex.GetBaseException();
    }

오류 페이지에 도달 할 때 (~/errors/generalerror.aspx.cs), server.getLasterror ()가 null입니다.

Global.asax.cs보다 오류 페이지에서 예외 세부 정보를 얻을 수있는 방법이 있습니까?

Vista/IIS7의 ASP.NET 3.5

도움이 되었습니까?

해결책

내 web.config 설정에서 더 자세히 살펴보면 주석 중 하나 이 게시물은 매우 도움이됩니다

ASP.NET 3.5 SP1에는 새로운 매개 변수 리디렉션 모드가 있습니다.

그래서 우리는 수정할 수 있습니다 customErrors 이 매개 변수를 추가하려면 :

<customErrors mode="RemoteOnly" defaultRedirect="~/errors/GeneralError.aspx" redirectMode="ResponseRewrite" />

그만큼 ResponseRewrite 모드를 사용하면 브라우저를 리디렉션하지 않고«오류 페이지»를로드 할 수 있으므로 URL은 동일하게 유지되며 중요한 것은 예외 정보가 손실되지 않습니다.

다른 팁

좋아,이 게시물을 찾았습니다.http://msdn.microsoft.com/en-us/library/aa479319.aspx

이 매우 예시적인 다이어그램으로 :

diagram
(원천: Microsoft.com)

본질적으로, 이러한 예외 세부 정보를 얻으려면 나중에 사용자 정의 오류 페이지에서 검색하려면 Global.asax에 직접 저장해야합니다.

가장 좋은 방법은 Global.asax에서 대부분의 작업을 수행하는 것 같습니다. 사용자 정의 오류 페이지는 논리가 아닌 유용한 콘텐츠를 처리합니다.

Nailitdown과 Victor가 말한 것의 조합. 선호하는/가장 쉬운 방법은 Global.asax를 사용하여 오류를 저장 한 다음 사용자 정의 오류 페이지로 리디렉션하는 것입니다.

Global.asax:

    void Application_Error(object sender, EventArgs e) 
{
    // Code that runs when an unhandled error occurs
    Exception ex = Server.GetLastError();
    Application["TheException"] = ex; //store the error for later
    Server.ClearError(); //clear the error so we can continue onwards
    Response.Redirect("~/myErrorPage.aspx"); //direct user to error page
}

또한 설정해야합니다 web.config:

  <system.web>
    <customErrors mode="RemoteOnly" defaultRedirect="~/myErrorPage.aspx">
    </customErrors>
  </system.web>

그리고 마지막으로, 당신이 저장 한 예외로 필요한 모든 것을하십시오. 오류 페이지:

protected void Page_Load(object sender, EventArgs e)
{

    // ... do stuff ...
    //we caught an exception in our Global.asax, do stuff with it.
    Exception caughtException = (Exception)Application["TheException"];
    //... do stuff ...
}

같은 것을 사용해보십시오 Server.Transfer("~/ErrorPage.aspx"); 내에서 Application_Error() Global.asax.cs의 방법

그런 다음 내부에서 Page_Load() Of ErrorPage.aspx.cs 당신은 다음과 같은 일을해도 괜찮을 것입니다. Exception exception = Server.GetLastError().GetBaseException();

Server.Transfer() 예외가 계속 매달려있는 것 같습니다.

여기에는 몇 가지 좋은 답변이 있지만 오류 페이지에 시스템 예외 메시지를 표시하는 것이 좋지 않다는 점을 지적해야합니다. 악의적 인 사용자에게 그렇게하고 싶지 않은 일을 실수로 공개 할 수 있습니다. 예를 들어 SQL Server Exception 메시지는 매우 장점이며 오류가 발생하면 데이터베이스의 사용자 이름, 암호 및 스키마 정보를 제공 할 수 있습니다. 해당 정보를 최종 사용자에게 표시해서는 안됩니다.

여기 내 해결책이 있습니다 ..

Global.aspx에서 :

void Application_Error(object sender, EventArgs e)
    {
        // Code that runs when an unhandled error occurs

        //direct user to error page 
        Server.Transfer("~/ErrorPages/Oops.aspx"); 
    }

에서 oops.aspx :

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadError(Server.GetLastError()); 
    }

    protected void LoadError(Exception objError)
    {
        if (objError != null)
        {
            StringBuilder lasterror = new StringBuilder();

            if (objError.Message != null)
            {
                lasterror.AppendLine("Message:");
                lasterror.AppendLine(objError.Message);
                lasterror.AppendLine();
            }

            if (objError.InnerException != null)
            {
                lasterror.AppendLine("InnerException:");
                lasterror.AppendLine(objError.InnerException.ToString());
                lasterror.AppendLine();
            }

            if (objError.Source != null)
            {
                lasterror.AppendLine("Source:");
                lasterror.AppendLine(objError.Source);
                lasterror.AppendLine();
            }

            if (objError.StackTrace != null)
            {
                lasterror.AppendLine("StackTrace:");
                lasterror.AppendLine(objError.StackTrace);
                lasterror.AppendLine();
            }

            ViewState.Add("LastError", lasterror.ToString());
        }
    }

   protected void btnReportError_Click(object sender, EventArgs e)
    {
        SendEmail();
    }

    public void SendEmail()
    {
        try
        {
            MailMessage msg = new MailMessage("webteam", "webteam");
            StringBuilder body = new StringBuilder();

            body.AppendLine("An unexcepted error has occurred.");
            body.AppendLine();

            body.AppendLine(ViewState["LastError"].ToString());

            msg.Subject = "Error";
            msg.Body = body.ToString();
            msg.IsBodyHtml = false;

            SmtpClient smtp = new SmtpClient("exchangeserver");
            smtp.Send(msg);
        }

        catch (Exception ex)
        {
            lblException.Text = ex.Message;
        }
    }

여기에 모두가 누락되었다고 생각한다는 중요한 고려 사항은로드 밸런싱 (웹 팜) 시나리오입니다. Global.asax를 실행하는 서버가 사용자 정의 오류 페이지 실행에 관한 서버와 다를 수 있으므로 응용 프로그램에서 예외 객체를 보관하는 것은 신뢰할 수 없습니다.

나는 여전히 웹 팜 구성 에서이 문제에 대한 신뢰할 수있는 솔루션을 찾고 있으며/또는 MS의 좋은 설명이 Server.getLasterror를 사용하여 사용자 정의 오류 페이지에서 예외를 선택할 수없는 이유에 대한 좋은 설명을 찾고 있습니다. Global.asax Application_error에서.

추신 : 먼저 잠금을 잠금하고 잠금 해제하지 않고 응용 프로그램 컬렉션에 데이터를 저장하는 것은 안전하지 않습니다.

이것은 아래의 두 가지 주제와 관련하여 오류 페이지에서 gethtmlerrormessage와 세션을 모두 원합니다.

responseerewrite 후 세션은 null입니다

httpcontext.session null이 redirectMode = responseereWrite가있는 이유는 무엇입니까?

나는 필요없는 해결책을 시도하고 보았다 Server.Transfer() or Response.Redirect()

먼저 : web.config에서 responseerewrite를 제거하십시오

web.config

<customErrors defaultRedirect="errorHandler.aspx" mode="On" />

그런 다음 global.asax

    void Application_Error(object sender, EventArgs e)
    {
         if(Context.IsCustomErrorEnabled)
         {     
            Exception ex = Server.GetLastError();
            Application["TheException"] = ex; //store the error for later
         }
    }

그런 다음 ErrorHandler.aspx.cs

        protected void Page_Load(object sender, EventArgs e)
            {       
                string htmlErrorMessage = string.Empty ;
                Exception ex = (Exception)Application["TheException"];
                string yourSessionValue = HttpContext.Current.Session["YourSessionId"].ToString();

                //continue with ex to get htmlErrorMessage 
                if(ex.GetHtmlErrorMessage() != null){              
                    htmlErrorMessage = ex.GetHtmlErrorMessage();
                }   
                // continue your code
            }

참고 문헌

http://www.developer.com/net/asp/article.php/3299641/servertransfer-vs-responseredirect.htm

그것은 나를 위해 일했다. MVC 5


안에 ~\Global.asax

void Application_Error(object sender, EventArgs e)
{
    FTools.LogException();
    Response.Redirect("/Error");
}


안에 ~\Controllers 만들다 ErrorController.cs

using System.Web.Mvc;

namespace MVC_WebApp.Controllers
{
    public class ErrorController : Controller
    {
        // GET: Error
        public ActionResult Index()
        {
            return View("Error");
        }
    }
}


안에 ~\Models 만들다 FunctionTools.cs

using System;
using System.Web;

namespace MVC_WebApp.Models
{
    public static class FTools
    {
        private static string _error;
        private static bool _isError;

        public static string GetLastError
        {
            get
            {
                string cashe = _error;
                HttpContext.Current.Server.ClearError();
                _error = null;
                _isError = false;
                return cashe;
            }
        }
        public static bool ThereIsError => _isError;

        public static void LogException()
        {
            Exception exc = HttpContext.Current.Server.GetLastError();
            if (exc == null) return;
            string errLog = "";
            errLog += "**********" + DateTime.Now + "**********\n";
            if (exc.InnerException != null)
            {
                errLog += "Inner Exception Type: ";
                errLog += exc.InnerException.GetType() + "\n";
                errLog += "Inner Exception: ";
                errLog += exc.InnerException.Message + "\n";
                errLog += "Inner Source: ";
                errLog += exc.InnerException.Source + "\n";
                if (exc.InnerException.StackTrace != null)
                {
                    errLog += "\nInner Stack Trace: " + "\n";
                    errLog += exc.InnerException.StackTrace + "\n";
                }
            }
            errLog += "Exception Type: ";
            errLog += exc.GetType().ToString() + "\n";
            errLog += "Exception: " + exc.Message + "\n";
            errLog += "\nStack Trace: " + "\n";
            if (exc.StackTrace != null)
            {
                errLog += exc.StackTrace + "\n";
            }
            _error = errLog;
            _isError = true;
        }
    }
}


안에 ~\Views 폴더를 만듭니다 Error그리고에서 ~\Views\Error 만들다 Error.cshtml

@using MVC_WebApp.Models
@{
    ViewBag.Title = "Error";
    if (FTools.ThereIsError == false)
    {
        if (Server.GetLastError() != null)
        {
            FTools.LogException();
        }
    }
    if (FTools.ThereIsError == false)
    {
        <br />
        <h1>No Problem!</h1>
    }
    else
    {
        string log = FTools.GetLastError;
        <div>@Html.Raw(log.Replace("\n", "<br />"))</div>
    }
}


이 주소를 입력하는 경우 localhost/Error open page Whithout Error



오류가 발생하는 경우 error occurs

오류를 표시하는 대신 데이터베이스에 저장할 변수 '로그'


원천: Microsoft asp.net

여기에 몇 가지 옵션이 있다고 생각합니다.

세션에 마지막 예외를 저장하고 사용자 정의 오류 페이지에서 검색 할 수 있습니다. 또는 application_error 이벤트 내에서 사용자 정의 오류 페이지로 리디렉션 할 수 있습니다. 후자를 선택하면 Server.Transfer 메소드를 사용해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top