1

SoapExtension があります。すべての Web サービスの要求と応答をログに記録します。プロジェクトには10​​00を超えるWebサービス呼び出しがあると思います。私の問題は、Web サービス呼び出しがタイムアウトまたは 403、404 などの httpexceptions で終了した場合、リクエストをログに記録できないことです。この種の例外もログに記録する必要があります。

これは私の 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();
    }

}
4

1 に答える 1

-2

次のテキストは、問題の解決に役立つ場合があります。

「SoapExtension ソリューション

この問題を解決するための最も一般的な方法 (私がこれまでに見つけたもの) は、カスタム SoapExtension サブクラスをコーディングすることです。これにより、Web サービスの要求と応答のさまざまな段階で SoapMessage への低レベルのアクセスが可能になります。未処理の例外が発生すると、SoapException を応答 SoapMessage で (Exception プロパティを介して) キャプチャできます。SoapException の InnerException プロパティには、実際の未処理の例外が含まれます。この時点で、ドアの外に出る途中で例外をログに記録できるので、技術サポート部門からその電子メールを受け取ったときに、何かを続けることができます.

しかし、実際に一般向けの Web サービス (私たちのようなもの) を開発したことがある場合は、単に例外をログに記録するだけでは不十分であることにすぐに同意するでしょう。多くの場合、呼び出し元に送り返される SoapException 自体の内容をもう少し制御したいことがあります。SoapExtension サブクラス アプローチを使用すると、SoapException を変更できますが、そのレベルは非常に低くなります。具体的には、代表的な SOAP エラー XML に既に逆シリアル化されており、カスタム コンテンツをそのエラーに挿入するために、高度なストリーム操作を行う必要があります (例: 詳細要素を追加します)。私の意見では、これはハックであり、非常に洗練されたソリューションではありません。代わりに、SoapException がスローされる前により多くの制御を行う必要があります。理想的には、SoapException を自分で作成してスローできれば、結果として発生する SOAP エラーの内容 (エラー コードや詳細など) をより詳細に制御できます。そうすれば、生の SOAP メッセージ自体を傍受して操作する必要がなくなります。」

詳細については、次のリンクを参照してください: http://beyondthispoint.blogspot.co.uk/2008/04/managing-unhandled-exceptions-in-aspnet.html

于 2013-03-05T14:35:52.960 に答える