我正在尝试使用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#类型提供程序的问题吗?
答案 0 :(得分:1)
在两种情况下,我遇到了运行已编译但未在FSI中运行的类型提供程序(反之亦然)的问题。你可能已经找到了第三个类型的提供者仍然有点尖端......
Common7
目录结构中,从那时起FSI(和类型提供者)总是使用那里的版本,因为Visual Studio正在加载它们在启动时。我花了几个月的时间才弄清楚发生了什么。不知道其中任何一个是你的问题,但可能值得一试。
答案 1 :(得分:1)
看起来问题是由WSDL引起的。该服务定义了一个名为&#34; UrlType&#34;的复杂类型,其中包含一个名为&#34; LNG&#34;的属性。不知何故,这被错误地合并到&#34; UrlTypeLNG&#34;中。我手动编辑了WSDL以使用普通字符串而不是复杂类型,现在它似乎正在工作。
答案 2 :(得分:0)
如果您正在使用无法编辑其WSDL的第三方服务,您仍然可以绕过此问题。诀窍是在定义WSDL服务类型时使用LocalSchemaFile
和ForceUpdate
。在.wsdlschema
中指定LocalSchemaFile
文件名会创建所述文件,并定期将缓存的WSDL存储在其中。要防止定期重新生成此文件,还应包括ForceUpdate = false
。这允许您更改类型提供程序使用的ad hoc WSDL。确保每次都重建以使更改生效。另请注意,如果更改了第三方服务的WSDL,则可能必须手动重做此过程。
类型定义可能如下所示:
type SomeService = WsdlService<"http://3rdparty.net/wsdl/srv.wsdl",
LocalSchemaFile = "srv_local.wsdlschema",
ForceUpdate = false>