Updated Answer -
After looking at your comment I got the point. So you want to supply the string and then cast it before OperationInovker comes into picture. So I got my hands dirty playing around and finally did it.
Here's What I have done. A new class that derives from WebHttpBehavior which would give a place where we can extend or override the existing behavior of WebHttpBidning.
public class MyWebHttpBehavior : WebHttpBehavior
{
}
Though it's a hack and but this would work. The problem with Typed argument was that the URL Template formatter was throwing exception by checking the method signature for type string so I got rid of that by over riding the BindingInformation by overiding method GetRequestDispatchFormatter.
protected override IDispatchMessageFormatter GetRequestDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint)
{
foreach (var item in operationDescription.Messages[0].Body.Parts)
{
item.Type = typeof(string);
}
return base.GetRequestDispatchFormatter(operationDescription, endpoint);
}
After applying this behavior the run time will no more throw exception for String argument check. Now I need to change the OperationInvoker because if you run this then this will throw excpetion when you invoke the opration from client saying Invalid cast.
Now here comes the IOperationInvoker in picture. I have simply taken the value from input[] of type object converted the value from String to Guid and passed it back to the Invoker.
public class ValueCastInvoker : IOperationInvoker
{
readonly IOperationInvoker _invoker;
public ValueCastInvoker(IOperationInvoker invoker)
{
_invoker = invoker;
}
public ValueCastInvoker(IOperationInvoker invoker, Type type, Object value)
{
_invoker = invoker;
}
public object[] AllocateInputs()
{
return _invoker.AllocateInputs().ToArray();
}
private object[] CastCorrections(object[] inputs)
{
Guid obj;
var value = inputs[0] as string;
if (Guid.TryParse(value, out obj))
{
return new[] { (object)obj }.Concat(inputs.Skip(1)).ToArray();
}
return inputs.ToArray();
}
public object Invoke(object instance, object[] inputs, out object[] outputs)
{
return _invoker.Invoke(instance, CastCorrections(inputs), out outputs);
}
public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
{
return _invoker.InvokeBegin(instance, inputs, callback, state);
}
public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
{
return _invoker.InvokeEnd(instance, out outputs, result);
}
public bool IsSynchronous
{
get { return _invoker.IsSynchronous; }
}
}
Now here what took me a long time to figure out is how to inject this custom operation inovker in pipeline. I found a relevants stackoverflow answer here. And implemented the way person suggested and it worked.
Adding summary here: A new IOperationBehavior has to be implemented and attach it with DispatcherRuntime.
public class MyOperationBehavior : IOperationBehavior
{
public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
{
}
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
dispatchOperation.Invoker = new ValueCastInvoker(dispatchOperation.Invoker);
}
public void Validate(OperationDescription operationDescription)
{
}
}
Now in MyWebHttpBehavior override the ApplyDispatchBehavior and introduce above implemented IOperationBehavior.
public override void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
foreach (var operation in endpoint.Contract.Operations)
{
if (operation.Behaviors.Contains(typeof(MyOperationBehavior)))
continue;
operation.Behaviors.Add(new MyOperationBehavior());
}
base.ApplyDispatchBehavior(endpoint, endpointDispatcher);
}
Now all these hacks and extensions would make this Legal.
[WebInvoke(Method = "GET", UriTemplate = "/{id}")]
string GetValue(Guid id);
Disclaimer: I had fun experimenting this exntesion and applying custom behavior but I havn't checked the impacted areas. So use it own your own risk and feel free to change/enhance as you may. Sorry for Typos.
Update 2
I have created a library to wrap this web http behavior extension. The library provides more support of other value types in method parameters(multiple). Check this out.