F#TypeProvider无法加载类型

时间:2015-01-24 06:21:48

标签: .net soap f# wsdl type-providers

我正在尝试使用F#类型提供程序编写一个简单的SOAP客户端。完整的计划是:

open System
open System.Runtime.Serialization
open System.ServiceModel
open Microsoft.FSharp.Data.TypeProviders

type EntrezService = WsdlService<"http://eutils.ncbi.nlm.nih.gov/soap/v2.0/eutils.wsdl">

[<EntryPoint>]
let main argv =
    let client = EntrezService.GeteUtilsServiceSoap()
    try
        let req = EntrezService.ServiceTypes.eSearchRequest()
        let res = client.run_eSearch req
        printfn "%A" res
    with
        | ex ->
            let rec inner (ex : Exception) =
                if ex.InnerException <> null then
                    inner ex.InnerException
                printfn "%s" ex.Message
            inner ex
    0

不幸的是,看起来应用程序在它甚至可以进行SOAP调用之前崩溃,具有以下TypeLoadException:

  

无法加载类型&#39; UrlTypeLNG&#39;来自装配&#39; EntrezGeneAdaptor,   Version = 0.0.0.0,Culture = neutral,PublicKeyToken = null&#39;。

此类型在WSDL中定义。我不知道为什么.NET会尝试从我的程序集中加载它。

堆栈跟踪表示从System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping抛出异常。

这里发生了什么,是否有一个简单的解决办法?等效的程序在C#中运行良好,这是F#类型提供程序的问题吗?

3 个答案:

答案 0 :(得分:1)

在两种情况下,我遇到了运行已编译但未在FSI中运行的类型提供程序(反之亦然)的问题。你可能已经找到了第三个类型的提供者仍然有点尖端......

  1. 使用类型提供程序在应用程序中缺少程序集绑定重定向。在这里查看一些assembly redirect instructions的FSharp.Core。
  2. GAC或Visual Studios执行目录中的库。我曾经有一个nuget包解压缩到某个地方的Visual Studio Common7目录结构中,从那时起FSI(和类型提供者)总是使用那里的版本,因为Visual Studio正在加载它们在启动时。我花了几个月的时间才弄清楚发生了什么。
  3. 不知道其中任何一个是你的问题,但可能值得一试。

答案 1 :(得分:1)

看起来问题是由WSDL引起的。该服务定义了一个名为&#34; UrlType&#34;的复杂类型,其中包含一个名为&#34; LNG&#34;的属性。不知何故,这被错误地合并到&#34; UrlTypeLNG&#34;中。我手动编辑了WSDL以使用普通字符串而不是复杂类型,现在它似乎正在工作。

答案 2 :(得分:0)

如果您正在使用无法编辑其WSDL的第三方服务,您仍然可以绕过此问题。诀窍是在定义WSDL服务类型时使用LocalSchemaFileForceUpdate。在.wsdlschema中指定LocalSchemaFile文件名会创建所述文件,并定期将缓存的WSDL存​​储在其中。要防止定期重新生成此文件,还应包括ForceUpdate = false。这允许您更改类型提供程序使用的ad hoc WSDL。确保每次都重建以使更改生效。另请注意,如果更改了第三方服务的WSDL,则可能必须手动重做此过程。

类型定义可能如下所示:

type SomeService = WsdlService<"http://3rdparty.net/wsdl/srv.wsdl",
                               LocalSchemaFile = "srv_local.wsdlschema",
                               ForceUpdate = false>