F#wsdl类型提供程序错误?

时间:2012-10-19 07:31:02

标签: wcf f# wsdl svcutil.exe type-providers

虽然我喜欢F#类型提供商的想法,但我第一次尝试使用它们的努力却很严重。

我打算用WsdlService<"http://someurl/some.svc?wsdl">

连接到服务(WCF)

它以史诗般的失败:

  

类型提供者   'Microsoft.FSharp.Data.TypeProviders.DesignTime.DataProviders'   报错:tmp6E6C.cs(9409,26):错误CS0644:   'System.ComponentModel.PropertyChangedEventHandler'无法派生自   特殊类'System.MulticastDelegate'   c:\ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ mscorlib.dll :(位置   与先前错误相关的符号)

以及许多其他可能不相关的警告:

  

tmp6E6C.cs(290,28):警告CS0436:类型   'System.Data.DataRowState'中   'c:\ Users \ someuser \ AppData \ Local \ Temp \ tmp6E6C.cs'与之冲突   导入类型'System.Data.DataRowState'中   'C:\ WINDOWS \ Microsoft.NET \框架\ v4.0.30319 \ System.Data.dll中'。运用   'c:\ Users \ someuser \ AppData \ Local \ Temp \ tmp6E6C.cs'中定义的类型。   tmp6E6C.cs(9427,17):(与先前警告相关的符号位置)

这是一个已知的功能;-)还是我使用它错了?

我遗憾的是无法发布WSDL,而且其中包含很多类型,因此我必须承认我有点懒,并且没有将其修剪掉。 OTOH如果我确实知道WSDL的哪个部分冒犯或创建了这个错误,我当然会把它放在这里。

要改变WSDL也不是一个选项,所以我主要想知道为什么F#WSDL类型提供程序无法处理这个(WCF)WSDL,或者我做错了什么。

在使用来自VS2010的C#和svcutil.exe时它非常出色。

我已经尝试了WsdlTypeProvider的所有参数,它们确实给出了相同的结果(当然除了ForceUpdate)。我应该用F#以另一种方式使用这些服务吗?

=============================================== ================================ 添加信息(因为我是新的,不想回答。不要问为什么:):

谢谢大家回答/评论。

我确实以某种方式去了自己(手动使用svcutil)。正如我上面所说,我试图手动使用svcutil,并且在编译生成的C#代码时失败(在F#之外的库中)。

也就是说,我做了以下事情:

1)通过在VS 2010 GUI中设置引用来创建合同。这按预期工作

2)尝试使用cmd-line中的svcutil创建它。然后该文件的编译失败并出现相同的错误。

从我的观点来看,似乎在cmd-line的svcutil中会发生什么,以及从GUI添加相同服务时使用svcutil(或使用的内容)时会发生什么,并不会生成具有相同参数的代码。我想这部分是由于我尝试使用的是WCF服务而不是“干净”的WSDL / webservice这一事实,而类型提供程序假定我尝试使用“干净”的Web服务。

我没有设法为svcutil找到任何params照顾这个,或任何可能的params组合,而不是说我尝试了所有组合的排列,但尝试基于(尝试)深入阅读的可能性svcutil的文档(从cmd-line开始使用它并不是新的。)

到目前为止,我已经得出结论,svcutil的一些“缺失”参数会导致这种情况,并且F#类型提供程序没有错。我仍然非常希望以某种方式解决它,仍然使用F#类型提供程序,但后退是通过C#中的GUI生成代码,然后再次引用F#中的那部分代码。这不是我试图实现的优雅解决方案,因为我确实有很多服务,我非常希望创建一个很好的原型设计和测试服务方式。

另一个后备当然也会放弃整个F#部分并且只是进行一些单元测试等,但这再次贬低了偷偷摸摸F#并同时学习的目的; - )

2 个答案:

答案 0 :(得分:3)

WSDL类型提供程序(以及其他一些提供程序)在后台使用SvcUtil来完成繁重的工作。如果打开taskprr的ProcExp或类似工具,可以看到在将TP代码粘贴到Visual Studio后生成的SvcUtil进程。至少使用ProcExp,您可以看到带有参数的完整命令行。

因此,确切了解TP为您的服务调用了什么SvcUtil命令行,并检查它是否在F#环境之外工作。

SvcUtil在C#/ VS 2010中运行的事实很有意思。我假设你现在使用的是F#TP,你现在在VS 2012上。如果是这样,SvcUtil本身的版本可能会有所不同,这可能是相关的。

特定错误似乎与解释here相同,因此您的服务代码中可能会有一些不完整的注释。

答案 1 :(得分:0)

我无法离开这个问题...

我现在做了以下事情:

  1. 使用普通香草设置运行svcutil:svcutil http://some.address/some/path.svc
  2. 运行更多设置:svcutil / r:&#34; C:\ Program Files(x86)\ Reference Assemblies \ Microsoft \ Framework.NETFramework \ v4.5 \ System.dll&#34; / r:&#34; C:\ Program Files(x86)\ Reference Assemblies \ Microsoft \ Framework.NETFramework \ v4.5 \ System.Data.dll&#34; http://some.address/some/path.svc
  3. 这确实会在C#文件中产生以下差异(它存在于1中)而在2)中不存在明显的差异):

    namespace System.ComponentModel
    {
        using System;
    
    
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
        [System.SerializableAttribute()]
        public partial class PropertyChangedEventHandler : System.MulticastDelegate
        {
    
            public PropertyChangedEventHandler(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : 
                    base(info, context)
            {
            }
        }
    }
    namespace System.Data
    {
        using System;
        using System.Runtime.Serialization;
    
    
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
        [System.FlagsAttribute()]
        [System.Runtime.Serialization.DataContractAttribute(Name="DataRowState", Namespace="http://schemas.datacontract.org/2004/07/System.Data")]
        public enum DataRowState : int
        {
    
            [System.Runtime.Serialization.EnumMemberAttribute()]
            Detached = 1,
    
            [System.Runtime.Serialization.EnumMemberAttribute()]
            Unchanged = 2,
    
            [System.Runtime.Serialization.EnumMemberAttribute()]
            Added = 4,
    
            [System.Runtime.Serialization.EnumMemberAttribute()]
            Deleted = 8,
    
            [System.Runtime.Serialization.EnumMemberAttribute()]
            Modified = 16,
        }
    }
    

    这又使文件在2中编译,并且正如预期的那样。

    有点奇怪的部分是:为什么运行svcutil时F#wsdl提供程序中没有使用System.dll? System.Data.dll我有点理解,因为在运行svcutil时默认使用它(至少根据文档)。

    OTOH我也认为文件说如果组件在GAC中,它应该使用它们。那么如何验证它们是否在那里,和/或如果没有它们将它们加载到组件中?

    运行gacutil -i System.dll(在System.dll 4.5版本上)提供:

      

    将程序集添加到缓存失败:尝试加载a   程序格式不正确。

    是64/32位问题吗? (我在64位窗口,如果它确实有任何相关性)

    或者重新解释这个问题:当我无法通过WsdlProvider-part直接添加引用时,如何在运行svcutil时将System.dll和System.Data.dll引入部分引用?

    我很确定它不使用System.dll,因为如果我将collectiontype参数添加到wsdlprovider:

    WsdlService<"http://some.url/some/path.svc", "c:\\temp\\wsdl\\some.wsdlschema", true, ".", true, true, false, false, "System.Collections.Generic.List'1">
    

    它还抱怨以下内容:

      

    类型提供者   &#39; Microsoft.FSharp.Data.TypeProviders.DesignTime.DataProviders&#39;   报告错误:错误:无法为该值加载任何类型   System.Collections.Generic.List&#39; 1传递给/ collectionType   选项。确保通过指定此类型所属的程序集   / reference选项。

    如果引用System.dll(我认为),应该可以直接使用。

    有任何进一步调查或解决此问题的想法吗?