5

For my WCF client, I'd like to be able to do some pre and post work for every operation of a given endpoint.

  • The pre work would like to make use of the operation name and the input arguments.
  • The post work would like to make use of (again) the operation name and the original input arguments as well as the outputs/return value or any exception that occurred.

Given this, the IParameterInspector (with its BeforeCall and AfterCall) gives me almost everything I need. The problem is that

  • in the case of an exception, AfterCall is not called (see here).

To help with that problem, I can add an IClientMessageInspector since its AfterReceiveReply does get called in the face of an exception. This gives me the ability to

  • determine if an exception (fault) occurred or not.
  • do post work in the face of an exception

Question:

  • Is there a way with the IClientMessageInspector.AfterReceiveReply to get (or create the equivalent) exception that represents what will eventually be thrown to the callers. And if so, is there a way to mark the exception as handled such that the callers will not get the exception?
  • Or, is there some other extensibility mechanism or other approach I should be using to meet my goals?
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 回答