WCF 客户端扩展性:IParemeterInspector.AfterCall 和异常处理

Mat*_*ith 5 c# wcf wcf-extensions

对于我的 WCF 客户端,我希望能够为给定端点的每个操作做一些前期后期工作。

  • 前期工作想利用的操作名称输入参数
  • 职位的工作想利用(再次)的的操作名称原始输入参数以及在输出/返回值 任何异常发生。

鉴于此,IParameterInspector(及其BeforeCallAfterCall)给了我几乎所有我需要的东西。问题是

  • 在异常的情况下,AfterCall不会被调用(请参阅此处)。

为了帮助解决这个问题,我可以添加一个,IClientMessageInspector因为它AfterReceiveReply确实会在遇到异常时被调用。这让我有能力

  • 确定是否发生异常(故障)。
  • 面对异常做后期工作

题:

  • 有没有办法IClientMessageInspector.AfterReceiveReply获取(或创建等效的)异常来表示最终将抛出给调用者的内容。如果是这样,有没有办法将异常标记为已处理,以便调用者不会收到异常?
  • 或者,我应该使用其他一些可扩展性机制或其他方法来实现我的目标吗?

Yoh*_*all 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
}
Run Code Online (Sandbox Code Playgroud)

消息格式化程序:

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
}
Run Code Online (Sandbox Code Playgroud)

最后是消息检查器:

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
}
Run Code Online (Sandbox Code Playgroud)