F# WsdlService type provider proxy

我与影子孤独终老i 提交于 2019-12-24 05:59:20

问题


I am following the MSDN tutorial for the WsdlService type provider found here. When I run it at home, it works as expected. When I write the same code at work, I am getting a design time exception:

The type provider 'Microsoft.FSharp.Data.TypeProviders.DesignTime.DataProviders' reported an error: Error: Cannot obtain Metadata from http://msrmaps.com/TerraService2.asmx?WSDL

Work does use a proxy and I have to alter the web.config to use a default proxy when consuming WSDL from a C# project in VS2012. When I looked at the parameters for the type provider, I don't see a mention about a proxy. Does anyone have any suggestions?

Thanks in advance.


回答1:


I'm not connecting through a proxy, so I have no way of actually testing this, but I think you should be able to use local WSDL file to load the type provider in the designer.

Try downloading the WSDL schema (from http://msrmaps.com/TerraService2.asmx?WSDL) and saving that to a local file (such as C:\temp\terra.wsdlschema). Then you should be able to write:

#r "System.ServiceModel.dll"
#r "FSharp.Data.TypeProviders.dll"
open Microsoft.FSharp.Data.TypeProviders

type Terra = WsdlService< ServiceUri="N/A", ForceUpdate = false, 
                          LocalSchemaFile = @"C:\temp\terra.wsdlschema">
let terra = Terra.GetTerraServiceSoap()
terra.GetPlaceList("New York", 1, false)

The ServiceUri parameter seems to be required, but it should be ignored if you add ForceUpdate=false. It should only require the cached WSDL file. I'm not entirely sure how to configure the runtime to use your config file setting, but I'm sure this can be done in some way (either it just works or you can pass something to the GetTerraServiceSoap method).

Sadly, the type provider does not statically know (at design time) where to look for the config file, so it ignores it.




回答2:


Expanding on Tomas's answer...

This is a common pattern in the built-in type providers today:

  1. At design time, if you need any kind of non-default configuration (e.g. credentials, proxy config, ...), the type provider will not work. You need to download some schema file locally (e.g. DB schema file, ODATA $metadata file, WSDL schema file...), and point the type provider at that, usually by passing LocalSchemaFile="...", ForceUpdate=false in the static constructor. This feeds the TP all the info it needs to generate the types.
  2. Then, you set all of your non-default config programmatically on the objects that are created for you, so that everything works at runtime.

Here's another example of essentially the same issue, where this pattern is used to set credentials.

In the case of WSDL, below is the programmatic approach to set the proxy after-the-fact (i.e. step #2). Cribbed entirely from this answer, which is exactly what you want, in C#. You'll probably need to play with this a bit to make it work for you.

#r "System.ServiceModel.dll"
#r "FSharp.Data.TypeProviders.dll"
open Microsoft.FSharp.Data.TypeProviders

type Terra = WsdlService< ServiceUri="N/A", ForceUpdate = false, 
                          LocalSchemaFile = @"C:\temp\terra.wsdlschema">
let terra = Terra.GetTerraServiceSoap()

let binding = terra.DataContext.Endpoint.Binding :?> System.ServiceModel.BasicHttpBinding
binding.ProxyAddress <- System.Uri("http://127.0.0.1:8888")
binding.BypassProxyOnLocal <- false
binding.UseDefaultWebProxy <- false

terra.GetPlaceList("New York", 1, false)


来源:https://stackoverflow.com/questions/18981682/f-wsdlservice-type-provider-proxy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!