.NET 3.5를 사용하는 asp.net 웹 양식에서 다음 설정을 사용하여이 문제를 해결할 수있었습니다.
내가 구현 한 패턴은 헤더에 올바른 HTTP 상태 코드를 사용하여 모든 시나리오를 처리하도록 직접 작성했기 때문에 web.config에서 .NET의 사용자 지정 리디렉션 솔루션을 우회합니다.
먼저 web.config의 customErrors 섹션은 다음과 같습니다.
<customErrors mode="RemoteOnly" defaultRedirect="~/error.htm" />
이 설정은 CustomErrors 모드가 on으로 설정되어 있는지 확인하고, 이는 나중에 필요로하는 설정이며 error.htm의 defaultRedirect에 대한 all-else-fails 옵션을 제공합니다. 이것은 특정 오류에 대한 처리기가 없거나 끊어진 데이터베이스 연결 라인을 따라 무언가가있을 때 유용합니다.
둘째, 다음은 전역 asax 오류 이벤트입니다.
protected void Application_Error(object sender, EventArgs e)
{
HandleError();
}
private void HandleError()
{
var exception = Server.GetLastError();
if (exception == null) return;
var baseException = exception.GetBaseException();
bool errorHandled = _applicationErrorHandler.HandleError(baseException);
if (!errorHandled) return;
var lastError = Server.GetLastError();
if (null != lastError && HttpContext.Current.IsCustomErrorEnabled)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(lastError.GetBaseException());
Server.ClearError();
}
}
이 코드는 오류 처리 책임을 다른 클래스로 넘깁니다. 오류가 처리되지 않고 CustomErrors가 켜져 있으면 프로덕션 단계에서 오류가 처리되지 않은 경우가 있음을 의미합니다. 사용자가 볼 수 없도록 여기에서 지우지 만 Elmah에 로그인하여 무슨 일이 일어나고 있는지 알 수 있습니다.
applicationErrorHandler 클래스는 다음과 같습니다.
public bool HandleError(Exception exception)
{
if (exception == null) return false;
var baseException = exception.GetBaseException();
Elmah.ErrorSignal.FromCurrentContext().Raise(baseException);
if (!HttpContext.Current.IsCustomErrorEnabled) return false;
try
{
var behavior = _responseBehaviorFactory.GetBehavior(exception);
if (behavior != null)
{
behavior.ExecuteRedirect();
return true;
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
return false;
}
이 클래스는 기본적으로 명령 패턴을 사용하여 발생한 오류 유형에 적합한 오류 처리기를 찾습니다. 이 수준에서 Exception.GetBaseException ()을 사용하는 것이 중요합니다. 거의 모든 오류가 상위 수준 예외로 래핑되기 때문입니다. 예를 들어 aspx 페이지에서 "throw new System.Exception ()"을 수행하면이 수준에서 System.Exception이 아닌 HttpUnhandledException이 수신됩니다.
"공장"코드는 간단하며 다음과 같습니다.
public ResponseBehaviorFactory()
{
_behaviors = new Dictionary<Type, Func<IResponseBehavior>>
{
{typeof(StoreException), () => new Found302StoreResponseBehavior()},
{typeof(HttpUnhandledException), () => new HttpExceptionResponseBehavior()},
{typeof(HttpException), () => new HttpExceptionResponseBehavior()},
{typeof(Exception), () => new Found302DefaultResponseBehavior()}
};
}
public IResponseBehavior GetBehavior(Exception exception)
{
if (exception == null) throw new ArgumentNullException("exception");
Func<IResponseBehavior> behavior;
bool tryGetValue = _behaviors.TryGetValue(exception.GetType(), out behavior);
if (!tryGetValue)
_behaviors.TryGetValue(typeof(Exception), out behavior);
if (behavior == null)
Elmah.ErrorSignal.FromCurrentContext().Raise(
new Exception(
"Danger! No Behavior defined for this Exception, therefore the user might have received a yellow screen of death!",
exception));
return behavior();
}
결국 확장 가능한 오류 처리 체계 설정이 있습니다. 정의 된 각 "동작"에는 오류 유형에 대한 사용자 지정 구현이 있습니다. 예를 들어, Http 예외는 상태 코드에 대해 검사되고 적절하게 처리됩니다. 404 상태 코드에는 Request.Redirect 대신 Server.Transfer가 헤더에 작성된 적절한 상태 코드와 함께 필요합니다.
도움이 되었기를 바랍니다.