【问题标题】:Interrogating the Protein Data Bank from F# 3.0从 F# 3.0 查询蛋白质数据库
【发布时间】:2012-08-19 12:05:19
【问题描述】:

practical Haskell example 鼓励我安装 Visual Studio 2012 试用版以使用 F# 类型提供程序。但是,我完全不知道如何使用它来解决这个问题。有一个RCSB SOAP web service。我使用来自 RCSB 的 WSDL Web 服务的 URL 复制了 an example(由于 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 service 也被弃用,取而代之的是 a RESTful one。我如何从 F# 3.0 使用它?最简单的工作示例是什么样的?

【问题讨论】:

    标签: web-services rest soap f# type-providers


    【解决方案1】:

    看起来操作BlastPDB 已重载,TypeProvider 使用的底层生成代码没有正确支持该操作(它没有将“1”放在正文名称上)。直接使用 Svcutil WCF: Svcutil generates invalid client proxy, Apache AXIS Web Service, overload operations 时,请参阅此答案以解决相同的问题 - 此页面显示 Type Provider uses svcutil internally

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

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

    以下是使用List all current PDB IDs 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
    

    【讨论】:

    • 所以类型提供者的唯一目的是使用静态类型接口自动生成代码,而它生成的代码是错误的?
    • WSDL 类型提供者的唯一目的是为 WSDL Web 服务提供类型。 F# 团队尽可能地重用了现有工具(没有必要写两次)。不幸的是,您立即发现了他们使用的工具中的一个错误。我怀疑 F# 团队是否意识到这一点,但我建议您将其作为错误提出(可能有解决方法)。
    • 类型提供程序发布时存在已知错误,但我不认为这是其中之一。
    • W3 Basic Profile 禁止重载。 WSDL 可能有问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-16
    • 1970-01-01
    • 2013-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多