如何在WCF中的AfterReceiveRequest上从OperationContext获取OperationDescription?

时间:2010-03-18 01:34:24

标签: wcf

在AfterReceiveRequest上实现IDispatchMessageInspector 我想检查是否对正在调用的当前操作应用了OperationBehavior。 所以我需要访问即将被调用的操作的OperationDescription? 有没有直接的方法,而不必将当前操作的Action与DispatchRuntime中的所有操作进行比较?

谢谢..

2 个答案:

答案 0 :(得分:6)

我有同样的问题,并通过以下方式解决。

OperationContext ctx = OperationContext.Current;
ServiceDescription hostDesc = ctx.Host.Description;
ServiceEndpoint endpoint = hostDesc.Endpoints.Find(ctx.IncomingMessageHeaders.To);
string operationName = ctx.IncomingMessageHeaders.Action.Replace(
  endpoint.Contract.Namespace + endpoint.Contract.Name + "/", "");
OperationDescription operation =
endpoint.Contract.Operations.Find(operationName);

这是msdn forum

的建议解决方案

答案 1 :(得分:2)

Noel Bj Kim的建议答案有效,除了这一行有问题:

ServiceEndpoint endpoint = hostDesc.Endpoints.Find(ctx.IncomingMessageHeaders.To);

我发现在IIS中托管WCF服务时,服务中使用的Uri可能与请求的不完全匹配 - 在我的情况下,“localhost”被请求但服务实际上是使用机器名称(例如“pc1.domain1.net”),而不是“localhost”。

我的解决方案可能不适合每个人的情况,只是根据方案和路径进行部分匹配。这有效地允许匹配http://localhost/Service1http://pc1.domain.net/Service1

/// <summary>
/// Find a service endpoint by partially matching the uri, but only against the Scheme and PathAndQuery elements.
/// This avoids issues with IIS hosting, where the actual Uri stored in the ServiceEndpoint may not exactly
/// match the one used in configuration.
/// </summary>
/// <param name="uri">Uri to match against</param>
/// <returns>A matching ServiceEndpoint, or null if no match was found.</returns>
private ServiceEndpoint FindServiceEndpointBySchemeAndQuery(Uri uri)
{
    foreach (var endpoint in OperationContext.Current.Host.Description.Endpoints)
    {
        if (endpoint.Address.Uri.Scheme == uri.Scheme
            && endpoint.Address.Uri.PathAndQuery == uri.PathAndQuery)
        {
            return endpoint;
        }
    }
    return null;
}

这样称呼:

ServiceEndpoint endpoint = FindServiceEndpointBySchemeAndQuery(ctx.IncomingMessageHeaders.To);