다음을 통해 공유


Extending Control Over Error Handling and Reporting

이 샘플에서는 WCF(Windows Communication Foundation) 서비스에서 IErrorHandler 인터페이스를 사용하여 오류 처리 및 오류 보고에 대한 제어를 확장하는 방법을 보여 줍니다. 샘플은 Getting Started 샘플을 기반으로 하며 오류를 처리하기 위한 몇 가지 코드가 서비스에 추가되었습니다. 클라이언트에서는 몇 가지 오류 조건을 발생시키고 서비스에서는 해당 오류를 가로채서 파일에 기록합니다.

ms751439.note(ko-kr,VS.100).gif참고:
이 샘플의 설치 절차 및 빌드 지침은 이 항목의 끝부분에 나와 있습니다.

서비스에서는 IErrorHandler 인터페이스를 사용하여 오류를 가로채고, 처리를 수행하고, 오류를 보고하는 방법에 영향을 줄 수 있습니다. 인터페이스에는 구현할 수 있는 두 개의 메서드 ProvideFaultHandleError가 있습니다. ProvideFault 메서드를 사용하면 예외에 대한 응답으로 생성되는 오류 메시지를 추가, 수정 또는 제거할 수 있습니다. 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 인터페이스를 구현해야 하며 비어 있는 public 생성자가 있어야 합니다. 그러면 이 특성에서 해당 오류 처리기 형식의 인스턴스를 만들어 서비스에 설치합니다. 이 작업을 수행하려면 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으로 나누기와 argument-out-of-range 조건을 발생시킵니다.

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으로 나누기와 argument-out-of-range 조건이 오류로 보고되는 것을 볼 수 있습니다. 클라이언트를 종료하려면 클라이언트 창에서 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.

샘플을 설치, 빌드 및 실행하려면

  1. Windows Communication Foundation 샘플의 일회 설치 절차를 수행했는지 확인합니다.

  2. 솔루션을 빌드하려면 Windows Communication Foundation 샘플 빌드의 지침을 따릅니다.

  3. error.txt 파일을 보관할 c:\logs 디렉터리를 만들었는지 확인합니다. 또는 CalculatorErrorHandler.HandleError에 사용된 파일 이름을 수정합니다.

  4. 단일 컴퓨터 또는 다중 컴퓨터 구성에서 샘플을 실행하려면 Running the Windows Communication Foundation Samples의 지침을 따릅니다.

ms751439.Important(ko-kr,VS.100).gif 참고:
컴퓨터에 이 샘플이 이미 설치되어 있을 수도 있습니다. 계속하기 전에 다음(기본) 디렉터리를 확인하십시오.

<InstallDrive>:\WF_WCF_Samples

이 디렉터리가 없으면 Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4로 이동하여 WCF(Windows Communication Foundation) 및 WF 샘플을 모두 다운로드하십시오. 이 샘플은 다음 디렉터리에 있습니다.

<InstallDrive>:\WF_WCF_Samples\WCF\Extensibility\ErrorHandling