更新回答 -
看着您的評論後,我得到了點。所以你想提供字符串,然後在OperationInovker進入圖片之前進行投射。所以我骯髒的玩弄了我的手,最後做到了。
這是我所做的。一個新的類從WebHttpBehavior
派生,這將給我們一個地方,我們可以擴展或覆蓋WebHttpBidning
的現有行爲。
public class MyWebHttpBehavior : WebHttpBehavior
{
}
雖然這是一個破解和但這會工作。鍵入參數的問題是,URL模板格式化程序通過檢查string
類型的方法簽名來拋出異常,所以我通過使用方法GetRequestDispatchFormatter
來控制BindingInformation
而擺脫了這種情況。
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);
}
應用此行爲後,運行時將不再爲String參數檢查拋出異常。現在我需要改變OperationInvoker,因爲如果你運行這個,那麼當你從客戶端調用Invalid cast
的操作時,這會引起不必要的反應。
現在來看圖片中的IOperationInvoker
。我只是將類型對象的input []中的值從String
轉換爲Guid
,並將其傳遞給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; }
}
}
現在,在這裏,我花了很長時間才弄清楚是如何注入這個自定義操作inovker管道。我發現了一個相關的stackoverflow答案here。並按照人們建議的方式實施。
在此處添加摘要:必須實施新的IOperationBehavior並將其與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)
{
}
}
現在MyWebHttpBehavior覆蓋ApplyDispatchBehavior
和介紹上述實施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);
}
現在所有這些黑客和擴展將使這個法律。
[WebInvoke(Method = "GET", UriTemplate = "/{id}")]
string GetValue(Guid id);
免責聲明:我很開心這個實驗和exntesion應用自定義行爲,但我沒有帶檢查受災地區。因此,請使用它自己的風險,並儘可能隨意更改/增強。 對不起,對錯字。
更新2
我創建了一個庫來包裝這個網頁的HTTP行爲擴展。該庫爲方法參數(多個)中的其他值類型提供更多支持。 Check this out。
在值被取出URI並傳入方法,你會認爲你可以轉換它...也許在MethodInvoker? – BenAlabaster
@BenAlabaster我已經更新了答案,是的,雖然MethodInvoker工作,但必須應用幾個黑客。希望你喜歡它並在這裏添加更多有價值的內容。 – vendettamit
...這裏是完整的代碼https://gist.github.com/vendettamit/a40f619c9dfcc3026635#file-webhttpbehaviorextension-cs – vendettamit