ErrorHandling 샘플은 WCF(Windows Communication Foundation) 서비스에서 오류 처리 및 오류 보고에 대한 제어를 IErrorHandler 인터페이스를 통해 확장하는 방법을 보여 줍니다. 샘플은 오류를 처리하기 위해 서비스에 추가된 몇 가지 추가 코드를 사용하여 시작하기 를 기반으로 합니다. 클라이언트는 몇 가지 오류 조건을 강제합니다. 서비스는 오류를 가로채 파일에 기록합니다.
비고
이 샘플에 대한 설치 절차 및 빌드 지침은 이 항목의 끝에 있습니다.
서비스는 오류를 가로채고, 처리를 수행하며, 인터페이스를 사용하여 IErrorHandler 오류를 보고하는 방법에 영향을 줄 수 있습니다. 인터페이스에는 구현할 수 있는 두 가지 메서드가 있습니다: ProvideFault(Exception, MessageVersion, Message) 및 HandleError. 이 ProvideFault(Exception, MessageVersion, Message) 메서드를 사용하면 예외에 대한 응답으로 생성된 오류 메시지를 추가, 수정 또는 표시하지 않을 수 있습니다. 이 HandleError 메서드를 사용하면 오류 발생 시 오류 처리가 수행되고 추가 오류 처리를 실행할 수 있는지 여부를 제어할 수 있습니다.
이 샘플에서, CalculatorErrorHandler
유형이 IErrorHandler 인터페이스를 구현합니다. 그 안에서
HandleError 메서드는 CalculatorErrorHandler
c:\logs의 Error.txt 텍스트 파일에 오류 로그를 씁니다. 샘플은 오류를 기록하며 이를 억제하지 않기 때문에 클라이언트에게 다시 보고 가능합니다.
public class CalculatorErrorHandler : IErrorHandler
{
// Provide a fault. The Message fault parameter can be replaced, or set to
// null to suppress reporting a fault.
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
}
// HandleError. Log an error, then allow the error to be handled as usual.
// Return true if the error is considered as already handled
public bool HandleError(Exception error)
{
using (TextWriter tw = File.AppendText(@"c:\logs\error.txt"))
{
if (error != null)
{
tw.WriteLine("Exception: " + error.GetType().Name + " - " + error.Message);
}
tw.Close();
}
return true;
}
}
오류 ErrorBehaviorAttribute
처리기를 서비스에 등록하는 메커니즘으로 존재합니다. 이 특성은 단일 형식 매개 변수를 취합니다. 해당 형식은 인터페이스를 IErrorHandler 구현해야 하며 공용 빈 생성자가 있어야 합니다. 그런 다음, 특성은 해당 오류 처리기 유형의 인스턴스를 인스턴스화하고 서비스에 설치합니다. 인터페이스 IServiceBehavior를 구현하고 메서드 ApplyDispatchBehavior를 사용하여 오류 처리기의 인스턴스를 서비스에 추가함으로써 이 작업을 수행합니다.
// This attribute can be used to install a custom error handler for a service.
public class ErrorBehaviorAttribute : Attribute, IServiceBehavior
{
Type errorHandlerType;
public ErrorBehaviorAttribute(Type errorHandlerType)
{
this.errorHandlerType = errorHandlerType;
}
void IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
{
}
void IServiceBehavior.AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
{
}
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
{
IErrorHandler errorHandler;
try
{
errorHandler = (IErrorHandler)Activator.CreateInstance(errorHandlerType);
}
catch (MissingMethodException e)
{
throw new ArgumentException("The errorHandlerType specified in the ErrorBehaviorAttribute constructor must have a public empty constructor.", e);
}
catch (InvalidCastException e)
{
throw new ArgumentException("The errorHandlerType specified in the ErrorBehaviorAttribute constructor must implement System.ServiceModel.Dispatcher.IErrorHandler.", e);
}
foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
channelDispatcher.ErrorHandlers.Add(errorHandler);
}
}
}
샘플은 계산기 서비스를 구현합니다. 클라이언트는 잘못된 값으로 매개 변수를 제공하여 서비스에서 의도적으로 두 개의 오류가 발생합니다. 인터페이스 CalculatorErrorHandler
를 IErrorHandler 사용하여 로컬 파일에 오류를 기록한 다음 클라이언트에 다시 보고할 수 있습니다. 클라이언트는 강제로 0으로 나누기와 범위를 벗어난 인수 조건을 발생시킵니다.
try
{
Console.WriteLine("Forcing an error in Divide");
// Call the Divide service operation - trigger a divide by 0 error.
value1 = 22;
value2 = 0;
result = proxy.Divide(value1, value2);
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
}
catch (FaultException e)
{
Console.WriteLine("FaultException: " + e.GetType().Name + " - " + e.Message);
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.GetType().Name + " - " + e.Message);
}
샘플을 실행하면 작업 요청 및 응답이 클라이언트 콘솔 창에 표시됩니다. 0으로 나누기 및 범위를 벗어난 인수 조건이 오류로 보고되는 것을 볼 수 있습니다. 클라이언트 창에서 Enter 키를 눌러 클라이언트를 종료합니다.
Add(15,3) = 18
Subtract(145,76) = 69
Multiply(9,81) = 729
Forcing an error in Divide
FaultException: FaultException - Invalid Argument: The second argument must not be zero.
Forcing an error in Factorial
FaultException: FaultException - Invalid Argument: The argument must be greater than zero.
Press <ENTER> to terminate client.
파일 c:\logs\errors.txt 서비스에 의해 오류에 대해 기록된 정보를 포함합니다. 서비스가 디렉터리에 쓰려면 서비스가 실행되는 프로세스(일반적으로 ASP.NET 또는 네트워크 서비스)에 디렉터리에 쓸 수 있는 권한이 있는지 확인해야 합니다.
Fault: Reason = Invalid Argument: The second argument must not be zero.
Fault: Reason = Invalid Argument: The argument must be greater than zero.
샘플을 설정, 빌드 및 실행하려면
Windows Communication Foundation 샘플 에 대한One-Time 설정 절차를 수행했는지 확인합니다.
솔루션을 빌드하려면 Windows Communication Foundation 샘플 빌드의 지침을 따릅니다.
c:\logs directory for the error.txt 파일을 만들었는지 확인하십시오.
CalculatorErrorHandler.HandleError
에 사용되는 파일 이름을 수정하거나 변경합니다.단일 또는 컴퓨터 간 구성에서 샘플을 실행하려면 Windows Communication Foundation 샘플실행의 지침을 따릅니다.