2010-03-18 2 views
3

В моей реализации IDispatchMessageInspector на AfterReceiveRequest Я хочу проверить, применяется ли OperationBehavior для текущей вызываемой операции. Итак, мне нужно получить доступ к OperationDescription операции, которая вот-вот будет вызвана ?? Любой прямой способ вместо того, чтобы сравнивать действие текущей операции со всеми в DispatchRuntime?Как получить OperationDescription из OperationContext в AfterReceiveRequest в WCF?

Спасибо ..

ответ

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

это не работает на сервере кластера. –

1

Предложенный ответ Ноэлем Bj Ким работает, за исключением того, эта линия является проблематичным:

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

Я обнаружил, что при размещении службы WCF в IIS, Uri, используемый в службе, может не соответствовать точному запросу - в моем случае было запрошено «localhost», но служба фактически использовала имя машины (например, «pc1.domain1.net»), а не «localhost».

Мое решение, которое может не работать для всех, заключается в том, чтобы просто выполнить частичное соответствие, основанное на схеме и пути. Это эффективно позволяет совпадение http://localhost/Service1 с http://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); 
Смежные вопросы