Как обрабатывать исключения Timeout в SoapExtension

У меня есть SoapExtension. Он регистрирует все мои запросы и ответы веб-сервисов. Я думаю, что в проекте более тысячи вызовов веб-сервисов. Моя проблема в том, что я не могу записать запрос в журнал, если мой вызов веб-службы заканчивается тайм-аутом или исключениями httpexceptions, такими как 403, 404 . Мне тоже нужно регистрировать подобные исключения.

Это мое SoapExtension

public class SoapLogger : SoapExtension
{
    Stream orgStream;
    Stream newStream;
    LogItem logItem;

    // When the SOAP extension is accessed for the first time, the XML Web
    // service method it is applied to is accessed to store the file
    // name passed in, using the corresponding SoapExtensionAttribute.    
    public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
    {
        return 0;
    }

    // The SOAP extension was configured to run using a configuration file
    // instead of an attribute applied to a specific XML Web service
    // method.
    public override object GetInitializer(Type WebServiceType)
    {
        return 0;
    }

    // Receive the file name stored by GetInitializer and store it in a
    // member variable for this specific instance.
    public override void Initialize(object initializer)
    {
        logItem = new LogItem();
    }

    // Save the Stream representing the SOAP request or SOAP response into
    // a local memory buffer.
    public override Stream ChainStream(Stream stream)
    {
        orgStream = stream;
        newStream = new MemoryStream();
        return newStream;
    }

    //  If the SoapMessageStage is such that the SoapRequest or
    //  SoapResponse is still in the SOAP format to be sent or received,
    //  save it out to a file.
    public override void ProcessMessage(SoapMessage message)
    {
        switch (message.Stage)
        {
            case SoapMessageStage.BeforeSerialize:
                break;
            case SoapMessageStage.AfterSerialize:
                WriteOutput();
                break;
            case SoapMessageStage.BeforeDeserialize:
                WriteInput(message);
                break;
            case SoapMessageStage.AfterDeserialize:
                CheckException(message);
                break;
            default:
                throw new Exception("invalid soap stage");
        }
    }

    public void CheckException(SoapMessage message)
    {

        logItem.WebClassName = message.MethodInfo.DeclaringType.FullName;
        logItem.WebMethodName = message.MethodInfo.Name;

        MethodBase method = FindMethod(logItem.WebMethodName);

        logItem.MethodName = method != null ? method.Name : "";
        logItem.ClassName = method != null ? method.DeclaringType.Name : "";

        logItem.Exception = message.Exception != null ? message.Exception.Message : "";

        LogToDB(logItem);
    }

    MethodBase FindMethod(string webMethodName)
    {
        try
        {
            StackFrame[] stackFrames = new StackTrace().GetFrames();

            int i;
            for (i = 0; i < stackFrames.Length; i++)
            {
                if (stackFrames[i].GetMethod().Name == webMethodName) break;
            }
            return i < stackFrames.Length - 1 ? stackFrames[i + 1].GetMethod() : null;
        }
        catch
        {
            return null;
        }
    }

    void LogToDB(LogItem logItem)
    {
        // I am logging logItem to db
    }

    public void WriteOutput()
    {
        newStream.Position = 0;

        logItem.Request = CopyString(newStream);
        logItem.StartTime = DateTime.Now;

        newStream.Position = 0;
        Copy(newStream, orgStream);
        newStream.Position = 0;
    }

    public void WriteInput(SoapMessage message)
    {
        Copy(orgStream, newStream);
        newStream.Position = 0;

        logItem.Response = CopyString(newStream);
        logItem.EndTime = DateTime.Now;

        newStream.Position = 0;
    }

    void Copy(Stream from, Stream to)
    {
        TextReader reader = new StreamReader(from);
        TextWriter writer = new StreamWriter(to);
        writer.WriteLine(reader.ReadToEnd());
        writer.Flush();
    }

    string CopyString(Stream from)
    {
        TextReader reader = new StreamReader(from);
        return reader.ReadToEnd();
    }

}

1 ответ

Следующий текст может помочь вам решить вашу проблему.

"Решение SoapExtension

Наиболее популярный подход к решению этой проблемы (который я обнаружил до сих пор) - это кодирование пользовательского подкласса SoapExtension, который обеспечивает низкоуровневый доступ к SoapMessage на разных этапах запроса и ответа веб-службы. Когда происходит необработанное исключение, исключение SoapException может быть зафиксировано в ответе SoapMessage (через свойство Exception). Свойство InnerException SoapException затем содержит фактическое необработанное исключение. На этом этапе вы можете зарегистрировать исключение на его выходе, так что, когда вы получите это электронное письмо от вашего отдела технической поддержки, у вас будет что делать.

Но если вы когда-либо разрабатывали настоящий общедоступный веб-сервис (как у нас), вы быстро согласитесь, что просто зарегистрировать исключение недостаточно. Часто вам требуется немного больше контроля над содержимым самого SoapException, которое отправляется обратно вызывающей стороне. Подкласс SoapExtension позволяет вам изменять SoapException, но на очень низком уровне. В частности, он уже десериализован в репрезентативный XML-код ошибки SOAP, и вам необходимо выполнить некоторые необычные манипуляции с потоком, чтобы вставить любое пользовательское содержимое в эту ошибку (например, добавить элемент detail). На мой взгляд, это взломанное и не очень элегантное решение. Вместо этого мы должны иметь больший контроль над SoapException, прежде чем он будет сгенерирован. В идеале, если бы мы могли сами создавать и генерировать исключение SoapException, мы могли бы иметь гораздо больший контроль над содержимым повторяющейся ошибки SOAP (такой как код ошибки и детализация). Тогда нам не пришлось бы беспокоиться о перехвате и обработке самих необработанных SOAP-сообщений ".

Пожалуйста, посетите ссылку для дополнительной информации: http://beyondthispoint.blogspot.co.uk/2008/04/managing-unhandled-exceptions-in-aspnet.html

Другие вопросы по тегам