2. 2
요구사항
■ 요구사항
- 웹 어플리케이션의 서버측 예외를 클라이언트에 보내지 말라.
예를 들어, “Error.htm”같은 페이지를 리턴하라.
- 현재 운영되는 어플리케이션 코드는 수정하지 않고, configuation 또는 공통 모듈 수정만으로 해결하라.
이 요구사항을 만족하는 기술적인 방법은 간단하다.
3. 3
예외 처리 #1
<!– IIS6 이하/IIS7.x 클래식 모드 -->
<system.web>
<!--handled by ASPX /-->
<customErrors …/>
</system.web>
<!– IIS 7.x 이상, 통합 모드 -->
<!-- handled by IIS -->
<system.webServer>
<httpErrors…/>
</system.webServer>
■ 방법 #1
얼른 떠오르는 방법은 다음과 같은 익숙한 방법이다.
웹서버측에서 예외가 발생하면 아래와 같은 설정을 사용하면 쉽게 사용자 정의 오류 페이지로 리다이레트 시켜서 반환할 수 있다.
<customErrors/>, <httpErrors/>
☞ <customErrors/>
- IIS6 이하.
- ASP.NET 웹 어플리케이션을 포함한 .NET 어플리케이션에서 발생하는 예외를 처리하기 위해서 사용
☞ <httpErrors/>
- IIS7.x 이상에서 추가.
- .NET어플리케이션에서의 예외뿐만 아니라 IIS로 전달되는 모든 예외를 처리하기 위해서 사용.
- IIS7에는 <customErrors/>도 하위 호환성을 위해서 포함되어 있음.
- IIS7.x 관리자 경로 : 사이트 노드 선택 > ASP.NET 섹션 > .NET오류 페이지
4. 4
예외 처리 방법 #1 - <customErrors/>, <httpErrors/>
<system.web>
<!--handled by ASPX /-->
<customErrors mode="On" defaultRedirect="/Error.htm"/>
</system.web>
<!-- handled by IIS -->
HTTP 상태 코드별 예외 페이지를 지정한다. 아래 샘플은 모든 예외에 대해서 “Error.htm” 파일을 클라이언트로 보낸다.
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="PassThrough" defaultResponseMode="File">
<remove statusCode="400" />
<error statusCode="400" path="/Error.htm" />
<remove statusCode="401" />
<error statusCode="401" path="/Error.htm" />
<remove statusCode="403" />
<error statusCode="403" path="/Error.htm" />
<remove statusCode="404" />
<error statusCode="404" path="/Error.htm" />
<remove statusCode="405" />
<error statusCode="405" path="/Error.htm" />
<remove statusCode="406" />
<error statusCode="406" path="/Error.htm" />
<remove statusCode="500" />
<error statusCode="500" path="/Error.htm" />
<remove statusCode="501" />
<error statusCode="501" path="/Error.htm" />
<remove statusCode="502" />
<error statusCode="502" path="/Error.htm" />
</httpErrors>
</system.webServer>
5. 5
예외 처리 #1, 이슈
사이트
Web.config
(사용자 정의 예외처리 설정, Error.htm 반환 )
웹 애플리케이션
Service 어플리케이션
1) .aspx 부분적으로 NO
2) .svc NO
.aspx OK
하나의 웹 사이트 하위에 웹 어플리케이션과 웹 서비스 어플리케이션(.asmx, svc)이 함께 있는 경우, 문제가 발생한다.
웹 서비스를 호출한 클라이언트에서는 예외가 발생하면 인식할 수 있는 예외 메시지가 내려와야 한다. “Error.htm”같은 HTML 메시지
가 내려오면 클라이언트에서 예외가 발생한다. 클라이언트에서는 예외가 발생한 위치가 서버인지 클라이언트인지 확인할 수 없다.
즉 웹 서비스 호출시에는 서버특에서 예외가 발생하더라도 “Error.htm”을 반환하지 않고, 사용자가 정의한 예외 객체를 반환할 필요가
있다.
☞ Aspx 프로그램 실행 도중 예외가 발생하는 경우, 앞의 configuration은 OK ! 문제없다.
☞ aspx를 프로그램적으로 호출한다든가, 웹 서비스(asmx, svc)에서는 실행도중 오류가 발생하면 앞의 configuration은 문제가 된다.
6. 6
추가 예외 처리 #2
1)서비스 어플리케이션 내에 있는 .aspx 부분적으로 NO
클라이언트에서 Hyper link나 브라우저를 통해서 호출된 경우라면 <customErrors/>, <httpErrors>의 작동에 따라서 “Error.htm”을 반환하는
것이 맞다. 그러나, 예를 들어 윈폼 클라이언트에서 aspx를 프로그램적으로 예를 들어서 WebRequest같은 객체를 이용해서
호출한다면 이 경우는 “Error.htm”을 반환하면 클라이언트에서 예외가 발생한다.
이런 경우는 다른 방식으로 예외 처리를 해야 한다. 예를 들어 다음과 같은 방법을 사용할 수 있다.
서버에서 예외가 발생하면, “예외가 발생했다는 플래그를 문자열에 넣어서, 문자열을 반환”한다. 그렇게 하면 서버측에서는 <customErrors/>,
<httpErrors/>를 통과해서 클라이언트로 전달될 것이다. 클라이언트에서는 플래그의 포함 여부를 확인해서 서버측에서의 예외 발생을 확인
할 수 있다.
2) 웹 서비스(.svc) NO
웹 서비스에서 예외가 발생하는 경우, <customErrors/>, <httpErrors/>를 통과할 수 있는 방법은 <httpErrors/>의 특정 어트리뷰트 값을 사
용하면 된다.
<!-- handled by IIS -->
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="PassThrough" defaultResponseMode="File">
<remove statusCode="400" />
…
7. 7
참고) WCF 예외 처리
■ 요구사항
- 하나의 웹 어플리케이션에 ASP.NET과 WCF 서비스가 함께 포함되어 있는 있을때, WCF 서비스의 예외를 클라이언트로 그대로 보내는
대신에 자세한 오류 내용은 없애고, 단지 사용자 정의 오류 메시지만 클라이언트로 보내라.
■ 방법
- WCF 서비스 인스펙터 정의 사용
public class ErrorHandlerInspector : IErrorHandler
{
public bool HandleError(Exception error)
{
return !(error is FaultException);
}
public void ProvideFault(Exception e, System.ServiceModel.Channels.MessageVersion version
, ref System.ServiceModel.Channels.Message fault)
{
if (!(e is FaultException))
{
FaultException<ExceptionDetail> fex =
new FaultException<ExceptionDetail>(new ExceptionDetail(new Exception( “사용자정의 메시지”)),
new FaultReason(“사용자정의 메시지”), new FaultCode("서버오류"), null);
fault = Message.CreateMessage(version, fex.CreateMessageFault(), null);
}
}
}
정의한 WCF서비스 인스펙터를 configuration에 추가하는 작업이 필요하다.
“WCF 인스펙터 등록”으로 구글링하면 찾아볼 수 있다. 달봉이 공부방에서도 정리하고 있다(http://dalbong2.net/199 )