7

这个实用的 Haskell 示例鼓励我安装 Visual Studio 2012 试用版,以便使用 F# 类型提供程序。但是,我完全不知道如何使用它来解决这个问题。有一个RCSB SOAP Web 服务。我使用来自 RCSB 的 WSDL Web 服务的 URL 复制了一个示例(由于 Web 服务 API 已更改,因此该示例不起作用):

open Microsoft.FSharp.Data.TypeProviders

type pdb = WsdlService<"http://www.rcsb.org/pdb/services/pdbws?wsdl">

do
    let ws = pdb.Getpdbws()
    ws.getCurrentPdbIds()
    |> printfn "%A"

但这在运行时崩溃并出现错误:

Unhandled Exception: System.InvalidOperationException: RPC Message blastPDBRequest1 in operation blastPDB1 has an invalid body name blastPDB. It must be blastPDB1
   at System.ServiceModel.Description.XmlSerializerOperationBehavior.Reflector.OperationReflector.EnsureMessageInfos()
   at System.ServiceModel.Description.XmlSerializerOperationBehavior.Reflector.EnsureMessageInfos()
   at System.ServiceModel.Description.XmlSerializerOperationBehavior.CreateFormatter()
   at System.ServiceModel.Description.XmlSerializerOperationBehavior.System.ServiceModel.Description.IOperationBehavior.ApplyClientBehavior(OperationDescription description, ClientOperation proxy)
   at System.ServiceModel.Description.DispatcherBuilder.BindOperations(ContractDescription contract, ClientRuntime proxy, DispatchRuntime dispatch)
   at System.ServiceModel.Description.DispatcherBuilder.ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime clientRuntime)
   at System.ServiceModel.Description.DispatcherBuilder.BuildProxyBehavior(ServiceEndpoint serviceEndpoint, BindingParameterCollection& parameters)
   at System.ServiceModel.Channels.ServiceChannelFactory.BuildChannelFactory(ServiceEndpoint serviceEndpoint, Boolean useActiveAutoClose)
   at System.ServiceModel.ChannelFactory.CreateFactory()
   at System.ServiceModel.ChannelFactory.OnOpening()
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.ChannelFactory.EnsureOpened()
   at System.ServiceModel.ChannelFactory`1.CreateChannel(EndpointAddress address, Uri via)
   at System.ServiceModel.ChannelFactory`1.CreateChannel()
   at System.ServiceModel.ClientBase`1.CreateChannel()
   at System.ServiceModel.ClientBase`1.CreateChannelInternal()
   at System.ServiceModel.ClientBase`1.get_Channel()
   at Program.pdb.ServiceTypes.PdbWebServiceClient.getCurrentPdbIds()
   at Program.pdb.ServiceTypes.SimpleDataContextTypes.PdbWebServiceClient.getCurrentPdbIds()
   at <StartupCode$ConsoleApplication2>.$Program.main@() in c:\users\jon\documents\visual studio 11\Projects\ConsoleApplication2\ConsoleApplication2\Program.fs: line 5

SOAP Web 服务也被弃用,取而代之的是 RESTful服务。我如何从 F# 3.0 使用它?最简单的工作示例是什么样的?

4

1 回答 1

7

看起来操作BlastPDB已重载,并且 TypeProvider 使用的底层生成代码没有正确支持(它没有将“1”放在正文名称上)。直接使用 Svcutil WCF 时,请参阅此答案以了解相同的问题:Svcutil 生成无效的客户端代理、Apache AXIS Web 服务、重载操作- 此页面显示类型提供程序在内部使用 svcutil

AFAIK 您将无法使用类型提供程序访问 REST 服务,因为 REST 服务不提供架构(请参阅此答案F# Type Providers and REST apis)。您可能不得不使用 REST 客户端库(请参阅此处的一些选项.NET Rest Client Frameworks)或执行原始 HTTP。

最简单的工作示例是什么样的?

以下是一个使用列出所有当前 PDB ID REST API获取当前 PDB id 列表的简单示例(我相信这相当于您尝试使用 Web 服务进行的调用)。您需要添加对 System.Net.Http 的引用。

open System.Net.Http
open System.Threading.Tasks

[<EntryPoint>]
let main argv = 

    use httpClient = new HttpClient()
    let task = httpClient.GetStringAsync("http://www.rcsb.org/pdb/rest/getCurrent")
    printfn "%s" task.Result

    0
于 2012-08-19T12:36:50.440 回答