WCF: получение MethodInfo из OperationContext - PullRequest
17 голосов
/ 12 мая 2009

Есть ли элегантный способ получить метод, который будет выполняться на экземпляре службы, из MessageInspector / AuthorizationPolicy / какой-либо другой точки расширения? Я мог бы использовать

OperationContext.Current.IncomingMessageHeaders.Action

но я надеюсь, что есть способ сделать это без ручного сопоставления действий SOAP с OperationContracts.

То, что я пытаюсь сделать, это проверить атрибуты метода перед его выполнением.

Ответы [ 4 ]

25 голосов
/ 01 октября 2009

Это заняло у меня целую вечность, но я нашел способ, который лучше, чем поиск и прохождение через весь контракт:

string action = operationContext.IncomingMessageHeaders.Action;
DispatchOperation operation = 
    operationContext.EndpointDispatcher.DispatchRuntime.Operations.FirstOrDefault(o =>
        o.Action == action);
// Insert your own error-handling here if (operation == null)
Type hostType = operationContext.Host.Description.ServiceType;
MethodInfo method = hostType.GetMethod(operation.Name);

И вот вы здесь. Вы можете получить атрибуты или делать все что угодно.

Примечание: у вас может возникнуть желание использовать OperationSelector в DispatchRuntime. Проблема, которую я обнаружил, заключалась в том, что в моем случае, на определенном этапе обработки, OperationSelector был нулевой ссылкой. Если у вас есть доступ к этому свойству, возможно, его быстрее и надежнее использовать, чем «сканировать» коллекцию OperationCollection, как указано выше.

14 голосов
/ 11 апреля 2011

Если OperationContext.CurrentIncomingMessageHeaders.Action равно нулю, вы можете сделать это - это немного кратче:

string actionName = OperationContext.Current.IncomingMessageProperties["HttpOperationName"] as string;
Type hostType = operationContext.Host.Description.ServiceType;
MethodInfo method = hostType.GetMethod(actionName);
7 голосов
/ 05 апреля 2012

На основе ответов @Aaronaught и @TimDog и этого вопроса SO Я нашел решение, которое должно работать как для REST, так и для SOAP .

///<summary>Returns the Method info for the method (OperationContract) that is called in this WCF request.</summary>
System.Reflection.MethodInfo GetActionMethodInfo(System.ServiceModel.OperationContext operationContext ){
    string bindingName = operationContext.EndpointDispatcher.ChannelDispatcher.BindingName;
    string methodName;
    if(bindingName.Contains("WebHttpBinding")){
            //REST request
            methodName = (string) operationContext.IncomingMessageProperties["HttpOperationName"];
    }else{
            //SOAP request
            string action = operationContext.IncomingMessageHeaders.Action;
            methodName = operationContext.EndpointDispatcher.DispatchRuntime.Operations.FirstOrDefault(o =>o.Action == action).Name;
    }
    // Insert your own error-handling here if (operation == null)
    Type hostType = operationContext.Host.Description.ServiceType;
    return hostType.GetMethod(methodName);
}
1 голос
/ 12 мая 2009

Средство интеграции Castle WCF позволяет вам делать это (среди многих полезных вещей) с помощью прокси-серверов DynamicProxy. Взгляните здесь .

На нем не так много документации, поэтому для документации о том, как его использовать, лучше взглянуть на его тесты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...