Как получить OperationDescription из OperationContext на AfterReceiveRequest в WCF? - PullRequest
3 голосов
/ 18 марта 2010

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

Спасибо ..

Ответы [ 2 ]

6 голосов
/ 17 мая 2011

У меня была такая же проблема, и я решил ее ниже.

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

2 голосов
/ 03 июля 2012

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

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...