我已经为某些自定义日志记录类型的功能实现了IClientMessageInspectorIDispatchMessageInspector。在使这一切变得更“可插入”的过程中,我的每个实现现在都调用其他具有CanProcess(object)方法的代码。 (例如,有许多不同的插件,因此我需要找到一个可以处理Message对象的插件。)

由于MyClientMessageInspector.BeforeSendRequestMyDispatchMessageInspector.AfterReceiveRequest实现都使用System.ServiceModel.Channels.Message类作为消息的实现接口,因此我需要一种可靠的方式来知道我拥有的“哪个”消息-一个在客户端上,还是一个从服务器?可悲的是,基础类BufferedMessageBodyWriterMessage都被标记为内部,所以我不能使用它们。

我输入了我讨厌的字符串比较技巧,但是它有效

这是DispatchMessageInspector调用的我的CanProcess方法:

public bool CanProcess(object testObject)
{
    return (testObject != null)
        && (testObject is System.ServiceModel.Channels.Message)
        && (testObject.GetType().UnderlyingSystemType
    .FullName == "System.ServiceModel.Channels.BufferedMessage");
}


这与ClientMessageInspector调用的相同:

public bool CanProcess(object testObject)
{
    return (testObject != null)
        && (testObject is System.ServiceModel.Channels.Message)
        && (testObject.GetType().UnderlyingSystemType
   .FullName == "System.ServiceModel.Channels.BodyWriterMessage");
}


有什么想法吗?我忽略了Message.Properties中的某些内容,还是Message的另一个属性来区分它们?

我完全讨厌这个字符串比较技巧。

最佳答案

您可以使用MessageHeaders进行自定义标识。

这是自定义WCF消息检查器的示例,其中填充了标头:

public class WCFMessageInspector : IClientMessageInspector
{

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        //in this sample I use predefined Guid to distinct specific client...
        Guid clientId = new Guid("5DBD6E89-81F2-4786-BC93-2758A8368A5D");
        MessageHeader<Guid> header = new MessageHeader<Guid>((Guid)clientId);
        MessageHeader untyped = header.GetUntypedHeader("Identity", "http://www.MyCustomNamespace.com");
        request.Headers.Add(untyped);
        return null;
    }
}


在接收端,您可以阅读以下消息标头:

MessageHeaders headers = OperationContext.Current.IncomingMessageHeaders;
try
{
    Guid clientId = headers.GetHeader<Guid>("Identity", "http://www.MyCustomNamespace.com");
    if (clientId == new Guid("5DBD6E89-81F2-4786-BC93-2758A8368A5D")
    {
        //TODO: this is our target client, do your stuff here...
    }
}
catch (Exception)
{
}


最佳实践还应将密钥字符串/ Guid放在单独的库中,并从那里读取值。

10-07 20:01
查看更多