5

私の WCF クライアントでは、特定のエンドポイントのすべての操作に対して事前および事後作業を実行できるようにしたいと考えています。

  • の作業では、操作名入力引数を利用したいと考えています。
  • 投稿作業では、操作名元の入力引数出力/戻り値 、または発生した例外を(再び) 利用したいと考えています。

これを考えると、IParameterInspector( とBeforeCallを含む ) は、必要なものをほとんどすべてAfterCall提供してくれます。問題はそれです

  • 例外の場合はAfterCall呼び出されません (こちらを参照)。

この問題を解決するために、例外が発生したときに呼び出されるIClientMessageInspectorので、を追加できます。AfterReceiveReplyこれにより、次のことが可能になります

  • 例外 (フォルト) が発生したかどうかを判断します。
  • 例外に直面して投稿作業を行う

質問:

  • 最終的に呼び出し元にスローされるものを表す例外IClientMessageInspector.AfterReceiveReplyを取得 (または同等のものを作成) する方法はありますか? もしそうなら、呼び出し元が例外を取得しないように例外を処理済みとしてマークする方法はありますか?
  • または、目標を達成するために使用すべき他の拡張メカニズムまたは他のアプローチはありますか?
4

1 に答える 1

0

私が正しく理解している場合は、すべての例外をミュートしたいと考えています。でメッセージを置き換え、 でIClientMessageInspector.AfterReceiveReply新しいメッセージを「逆シリアル化」することで可能IClientMessageFormatter.DeserializeReplyです。

以下のコードは、例外がスローされたときに結果値としてデフォルト値を返します。

メッセージ:

public sealed class FakeMessage : Message
{
    #region Fields

    private MessageProperties properties;
    private MessageHeaders headers;

    #endregion

    #region Constructors

    public FakeMessage(MessageVersion version, string action)
    {
        this.headers = new MessageHeaders(version);
        this.headers.Action = action;
    }

    #endregion

    #region Message Members

    public override MessageHeaders Headers
    {
        get { return headers; }
    }

    protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
    {
        throw new NotSupportedException();
    }

    public override MessageProperties Properties
    {
        get
        {
            if (this.properties == null)
            { properties = new MessageProperties(); }

            return properties;
        }
    }

    public override MessageVersion Version
    {
        get { return headers.MessageVersion; }
    }

    #endregion
}

メッセージ フォーマッタ:

public sealed class FakeMessageFormatter : IClientMessageFormatter
{
    #region Fields

    private IClientMessageFormatter baseFormatter;
    private object defaultReturnValue;

    #endregion

    #region Construcotrs

    public FakeMessageFormatter(IClientMessageFormatter baseFormatter, Type returnType)
    {
        this.baseFormatter = baseFormatter;

        if (returnType.IsValueType && returnType != typeof(void))
        { this.defaultReturnValue = Activator.CreateInstance(returnType); }
    }

    #endregion

    #region IClientMessageFormatter Members

    public object DeserializeReply(Message message, object[] parameters)
    {
        if (message is FakeMessage)
        { return defaultReturnValue; }

        return baseFormatter.DeserializeReply(message, parameters);
    }

    public Message SerializeRequest(MessageVersion messageVersion, object[] parameters)
    {
        return baseFormatter.SerializeRequest(messageVersion, parameters);
    }

    #endregion
}

そして最後にメッセージインスペクター:

public sealed class FakeMessageInspector : IClientMessageInspector
{
    #region IClientMessageInspector Members

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        if (reply.IsFault)
        { reply = new FakeMessage(reply.Version, (string)correlationState); }
    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        return request.Headers.Action + "Response";
    }

    #endregion
}
于 2015-03-21T00:06:14.167 に答える