2009-05-12 14 views
17

Czy istnieje elegancki sposób uzyskać metodę, która zostanie wykonana na wystąpienie usługi z MessageInspector/AuthorizationPolicy/niektóre inne punktu rozszerzenia? Mógłbym użyćWCF: Pobieranie MethodInfo z OperationContext

OperationContext.Current.IncomingMessageHeaders.Action

ale mam nadzieję, że istnieje jakiś sposób, aby to zrobić bez konieczności ręcznego dopasowania działania mydło z OperationContracts.

Próbuję sprawdzić atrybuty metody przed jej wykonaniem.

Odpowiedz

24

zajęło mi wieki, ale znalazłem sposób, który jest lepszy niż znalezienie i pobijania przez cały zamówienia:

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); 

i tam jesteś. Możesz zdobyć atrybuty lub zrobić cokolwiek innego.

Uwaga: Możesz ulec pokusie, aby spróbować użyć narzędzia OperationSelector w DispatchRuntime. Problemem, który znalazłem, było to, że w moim przypadku, na danym etapie przetwarzania, OperationSelector był referencją zerową. Jeśli masz dostęp do tej właściwości, prawdopodobnie jest to szybsze i bardziej niezawodne w użyciu niż "skanowanie" kolekcji OperationCore zgodnie z powyższym opisem.

+0

zaoszczędziło mi dużo czasu. Dzięki. – user80855

+0

DispatchOperation nie zawiera definicji FirstOrDefault? – fuzz

+1

@Fulvio: Upewnij się, że dodano odwołanie do przestrzeni nazw do "System.Linq". – Aaronaught

1

Funkcja integracji WCF Castle pozwala to zrobić (wśród wielu użytecznych rzeczy) za pomocą proxy DynamicProxy. Zobacz here.

Nie ma zbyt wiele dokumentacji na ten temat, więc dla dokumentów, jak z niego korzystać, najlepiej spojrzeć na jego testy.

+1

wydaje się overkill w moim przypadku, ale i tak dzięki –

13

Jeśli OperationContext.CurrentIncomingMessageHeaders.Action jest null, można to zrobić - to nieco terser:

string actionName = OperationContext.Current.IncomingMessageProperties["HttpOperationName"] as string; 
Type hostType = operationContext.Host.Description.ServiceType; 
MethodInfo method = hostType.GetMethod(actionName); 
+0

Czy to działa z przeciążonymi metodami? – Ahuman

7

Bazując na odpowiedziach @Aaronaught i @TimDog „s, a this SO question wymyśliłem rozwiązanie, które powinno działać zarówno dla REST i 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); 
} 
+0

Uwielbiam to !!!! Dzięki za ten mały klejnot. – ROFLwTIME

Powiązane problemy