2009-05-12 4 views
17

Existe-t-il un moyen élégant d'obtenir la méthode qui sera exécutée sur une instance de service à partir de MessageInspector/AuthorizationPolicy/un autre point d'extension? Je pourrais utiliserWCF: Récupération de MethodInfo à partir de OperationContext

OperationContext.Current.IncomingMessageHeaders.Action

mais j'espère qu'il ya un moyen de le faire sans correspondance manuellement les actions SOAP avec OperationContracts.

Ce que j'essaie de faire est d'examiner les attributs de la méthode avant son exécution.

Répondre

24

Il m'a fallu pour toujours, mais je l'ai trouver un moyen qui est mieux que de trouver et obstinés par l'ensemble du contrat:

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

Et là, vous êtes. Vous pouvez obtenir les attributs ou faire tout ce que vous voulez.

Remarque: Vous pourriez être tenté d'utiliser OperationSelector dans DispatchRuntime. Le problème que j'ai trouvé était que dans mon cas, à l'étape particulière du traitement, le OperationSelector était une référence nulle. Si vous avez accès à cette propriété, il est probablement plus rapide et plus fiable à utiliser que de "scanner" OperationCollection comme ci-dessus.

+0

m'a sauvé beaucoup de temps. Merci. – user80855

+0

DispatchOperation ne contient pas de définition pour FirstOrDefault? – fuzz

+1

@Fulvio: Assurez-vous d'avoir ajouté une référence d'espace de noms à 'System.Linq'. – Aaronaught

1

La fonction d'intégration WCF de Castle vous permet de faire exactement cela (entre autres choses utiles) en utilisant des proxies DynamicProxy. Regardez here.

Il n'y a pas beaucoup de documentation à ce sujet, donc pour les docs sur comment l'utiliser, il est préférable de jeter un oeil à ses tests.

+1

Semble une surpuissance dans mon cas, mais merci quand même –

13

Si OperationContext.CurrentIncomingMessageHeaders.Action est nulle, vous pouvez le faire - c'est un peu laconique:

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

Cela fonctionnerait-il avec des méthodes surchargées? – Ahuman

7

Sur la base des réponses de @Aaronaught et @TimDog, et this SO question je suis venu avec une solution qui devrait fonctionner pour REST et 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

J'adore !!!! Merci pour ce petit bijou. – ROFLwTIME

Questions connexes