如何将WCF方法绑定到任意URI

时间:2015-03-17 21:31:32

标签: c# wcf

我使用WCF(通过使用WebChannelFactory)来调用一些不受我控制的服务,这些服务是用各种技术实现的。从WCF的角度来看,我的界面只有一个方法,让我们称之为" get-stuff"。因此,这些服务可以通过http://www.service-a.com/get-stuffhttp://www.service-b.com/my-goodies/http://www.service-c.com/retrieve-thing.php

实施相同的方法

在所有示例中,我看到绑定到特定URI的方法是通过WebGet / WebInvoke属性的UriTemplate成员完成的。但这意味着," get-stuff"的所有URI。方法必须遵循固定的模板。例如,我可以创建一个UriTemplate =" / get-stuff",这样我的方法将始终绑定到/ get-stuff。

但是,我希望我的方法绑定到任意URI。顺便说一句,参数作为POST数据传递,所以我不需要担心将URI绑定到方法的参数。

2 个答案:

答案 0 :(得分:0)

你为什么不做这样的事呢

EndpointAddress endpointAddress = new EndpointAddress("any service url");
ChannelFactory<IMyService> channelFactory = new ChannelFactory<IMyService>(binding, endpointAddress);
IMyServiceclient = channelFactory.CreateChannel();
client.GetStuff();

答案 1 :(得分:0)

好的,通过在运行时修补WebInvokeAttribute的UriTemplate,我找到了解决问题的方法。我的单方法WCF接口是:

[ServiceContract]
interface IGetStuff
{
    [OperationContract]
    [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
    ResponseData GetStuff(RequestData request);
}

以下是我获取界面句柄的方法:

//Find the last portion of the URI path
var afterLastPathSepPos = uri.LastIndexOf('/', uri.Length - 2) + 1;
var contractDesc = ContractDescription.GetContract(typeof(IGetStuff));

foreach (var b in contractDesc.Operations[0].Behaviors)
{
    var webInvokeAttr = b as WebInvokeAttribute;

    if (webInvokeAttr != null)
    {
        //Patch the URI template to use the last portion of the path
        webInvokeAttr.UriTemplate = uri.Substring(afterLastPathSepPos, uri.Length - afterLastPathSepPos);
        break;
    }
}

var endPoint = new ServiceEndpoint(contractDesc, new WebHttpBinding(), new EndpointAddress(uri.Substring(0, afterLastPathSepPos)));

using (var wcf = new WebChannelFactory<I>(endPoint))
{
    var intf = wcf.CreateChannel();
    var result = intf.GetStuff(new RequestData(/*Fill the request data here*/));   //Voila!
}