【问题标题】:How to bind WCF methods to arbitrary URIs如何将 WCF 方法绑定到任意 URI
【发布时间】:2015-03-17 21:31:31
【问题描述】:

我使用 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 绑定到方法的参数。

【问题讨论】:

    标签: c# wcf


    【解决方案1】:

    你为什么不做这样的事情

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

    【讨论】:

    • 我相信 GetStuff() 方法将根据 UriTemplate 在 URI /get-stuff 上调用。我想要的是在 上调用 GetStuff() 方法,没有任何固定模板。
    • 据我所知,您连接的是服务本身,而不是方法。服务在取决于服务器代码的 URL 上公开。它没有任何方法名称。创建通道后,您可以调用接口共享的任何方法。
    • 不是真的,没有连接到服务的概念。当通过 WCF 调用远程 Web 方法时,所发生的一切就是将 HTTP 请求路由到特定的侦听器,然后该侦听器进行响应。实现可以像静态网页、WCF 服务、PHP 服务、node-JS、ASP.NET 或其他任何东西一样简单。
    【解决方案2】:

    好的,我找到了解决问题的方法,方法是在运行时修补 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!
    }
    

    【讨论】:

      猜你喜欢
      • 2014-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      • 2013-08-15
      • 2012-07-15
      相关资源
      最近更新 更多