Is there an elegant way to get the method that will be executed on a service instance from MessageInspector/AuthorizationPolicy/some other extension point? I could use
If OperationContext.CurrentIncomingMessageHeaders.Action
is null, you can do this -- it's a bit terser:
string actionName = OperationContext.Current.IncomingMessageProperties["HttpOperationName"] as string;
Type hostType = operationContext.Host.Description.ServiceType;
MethodInfo method = hostType.GetMethod(actionName);
It took me forever, but I did find a way that's better than finding and slogging through the entire contract:
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);
And there you are. You can get the attributes or do whatever else you like.
Note: You might be tempted to try to use the OperationSelector in the DispatchRuntime. The problem I found was that in my case, at the particular stage of processing, the OperationSelector was a null reference. If you have access to this property, it's probably faster and more reliable to use than "scanning" the OperationCollection as above.
Castle WCF integration facility enables you to do just that (among many useful things) by using DynamicProxy proxies. Take a look here.
There's not much documentation on it, so for docs on how to use it it's best to take a look at its tests.
Based on @Aaronaught and @TimDog 's answers, and this SO question I came up with a solution that should work for both REST and 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);
}