同步IClientMessageInspector和IParameterInspector之间的关联状态

时间:2012-12-28 17:34:59

标签: wcf

我有一个wcf客户端。根据要求,我需要记录请求中的一些元数据(以及请求中未包含的用户数据。)然后,如果请求成功,我可能必须记录响应元数据并根据标志,完整的肥皂要求。

我正在尝试以正确的方式执行此操作(使用IParameterInspector检查元数据和IClientMessageInspector以获取Soap),但我无法关联两个接口请求。我不确定这里的线程安全性。这是我在哪里的精简版...

     public class SoapRequestInfo
{
    public string UserId { get; set; }
    public Guid Key { get; set; }
    //would contain a lot more info
}

public class OperationProfilerParameterInspector : IParameterInspector, IClientMessageInspector
{
    //before serialization
    public object BeforeCall(string operationName, object[] inputs) //IParameterInspector
    {
        //Add the operation, record some specific inputs to db
        return new SoapRequestInfo
                            {
                                UserId = "1234",
                                Key = new Guid()
                            };
    }

    public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) //IParameterInspector
    {
       var info = correlationState as SoapRequestInfo;
        //Do some additional logging - easy enough
    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel) //IClientMessageInspector
    {
        //want to correlate this with IParameterInspector
        return null;
    }


    public void AfterReceiveReply(ref Message reply, object correlationState) //IClientMessageInspector
    {
        //May want to log full soap message depending on after call criteria
    }
}      

我知道我不能使用私有变量来保存Guid。我不能使用会话,因为可能有多个请求紧密连续,并不能保证响应是正确的。那么如何才能唯一地识别两个接口之间的correlationState?

2 个答案:

答案 0 :(得分:1)

如果您的服务在ASPNET兼容模式下运行,您可以使用HttpContext.Items保留您的对象,否则您可以使用TLS(线程本地存储),将数据放入插槽并稍后获取/清除。

答案 1 :(得分:-1)

可能你可以做这个有点不同的事情:

来自这篇文章passing correlation token to WCF service?

  

如果您使用带有WS-Addressing的消息版本,您应该自动拥有它,因为每条消息都将包含其自动生成的ID(guid),并且每个响应也将包含请求的ID。您可以通过OperationContext

访问这些标头

如果使用消息不符合您的要求,可能您可以尝试在发送请求时将自己的ID放在标题中,并可能使用相同的ID更新响应。