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

3
虽然我很喜欢F#类型提供程序的想法,但我的第一次尝试使用它们却失败了。我打算使用WsdlService<"http://someurl/some.svc?wsdl">连接到一个服务(WCF),但是它会崩溃并出现以下错误:“Microsoft.FSharp.Data.TypeProviders.DesignTime.DataProviders”类型提供程序报告了一个错误:tmp6E6C.cs(9409,26): error CS0644: “System.ComponentModel.PropertyChangedEventHandler”无法派生自特殊类“System.MulticastDelegate”c:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll:(与前一个错误相关的符号位置)还有很多其他警告,可能不相关:tmp6E6C.cs(290,28): warning CS0436:“System.Data.DataRowState”类型在“c:\Users\someuser\AppData\Local\Temp\tmp6E6C.cs”中与导入的类型“System.Data.DataRowState”在“c:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Data.dll”中发生冲突。使用在“c:\Users\someuser\AppData\Local\Temp\tmp6E6C.cs”中定义的类型。tmp6E6C.cs(9427,17):(与前一个警告相关的符号位置)。这是已知的问题吗(;-)),还是我使用方法错误?不幸的是,我不能发布WSDL,而且它相当大,其中包含很多类型,所以我必须承认我有点懒,也没有把它缩小。另一方面,如果我知道哪部分WSDL引起了问题或创建了这个错误,我当然会把它放在这里。更改WSDL也不是一个选项,所以我主要想知道为什么F# WSDL类型提供程序无法处理这个(WCF)WSDL,或者我做错了什么。当被C#和svcutil.exe从VS2010消耗时,它工作得非常好。我尝试了所有的WsdlTypeProvider参数,它们都给出了相同的结果(当然除了ForceUpdate)。我应该用另一种方式使用F#来消耗这些服务吗?===============================================================================添加信息(因为我是新手,不想回答。别问为什么:):谢谢你们所有人的回答/评论。我自己部分地走了这条路(手动使用svcutil)。正如我上面所说,我试图手动使用svcutil,但在生成的C#代码(在F#之外的库中)编译时失败。也就是说,我做了以下事情:1)通过在VS 2010 GUI中设置引用来创建合同。这符合预期2)尝试使用cmd-line中的svcutil创建它。然后,该文件的编译将失败并出现相同的错误。
从我的角度来看,从命令行使用svcutil和从GUI添加相同服务时生成的代码参数不同。我猜测这部分是由于我试图消费的是一个WCF服务而不是“干净”的WSDL / webservice,类型提供程序假定我尝试使用一个“干净”的webservice。
我没有找到任何参数能够解决这个问题,也没有找到任何可能的参数组合,虽然我并没有尝试所有的排列组合,但我尝试了一些基于阅读svcutil文档(我不是完全没有使用过它)的可行选项。
到目前为止,我得出的结论是这是svcutil中缺少某些参数引起的,F#类型提供程序并没有错。我仍然非常希望通过某种方式解决此问题,仍然使用F#类型提供程序,但备用方案是在C#中通过GUI生成代码,然后再次在F#中引用该代码部分。这不是我想要实现的优雅解决方案,因为我有很多服务,我非常希望创建这样一个很好的原型和测试服务的方式。
当然,另一个备选方案是放弃整个F#部分,只选择一些单元测试等,但这又违背了潜入F#并同时学习的目的。

“当使用C#和来自VS2010的svcutil.exe时,它的表现非常出色。” 这很有趣。我花了几天时间尝试使用类型提供程序与真实的Web服务(包括WSDL),但除了F#示例之外,我无法使任何东西正常工作。因此,我很感兴趣听到这可能是一个特定于F#的问题,而不是一般的.NET问题... - J D
我积极地认为这不是 .net 的问题(因为使用 svcutil 时它可以工作...),而是 WsdlProvider 或实际服务中存在的问题,可能是某个 WCF 在 WSDL 中进行了一些高级或狡猾的使用,而这些在提供程序实现中没有考虑到。当然,这也可能是我做错了什么。或者是所有因素的组合。很“好”听到其他人在使用它时也遇到了问题。在尝试使用 WsdlProviders 时,你遇到了什么错误?它也是针对 WCF 服务或其他创建的服务吗? - Helge Rene Urholm
如果没有看到具体的C#和F#代码,很难说“这在C#中可行但在F#中失败”。如果您能够发布两种语言中演示问题的小代码子集,那将非常有帮助。说两种不同语言的代码是相同的是一种很长的伸展。 - Onorio Catenacci
你为什么不发布WSDL?是因为安全性吗? - Robert Jeppesen
将外部顾问发布内部WSDL到互联网上,恐怕超出了允许的范围。正如已经确定的那样,这个问题与F#、C#或WSDL无关,而是与不同情况下如何处理WSDL之间的差异有关。 - Helge Rene Urholm
显示剩余3条评论
2个回答

3
WSDL类型提供程序(以及其他一些)在后台使用SvcUtil进行繁重的工作。如果您打开ProcExp或某个类似的工具的任务管理器,您可以看到在将TP代码粘贴到Visual Studio中后产生了SvcUtil进程。至少使用ProcExp,您可以查看使用的带有参数的完整命令行。
因此,请确定为您的服务调用了哪个SvcUtil命令行,并检查它是否在F#环境之外正常工作。
SvcUtil在C#/VS 2010中有效的事实很有趣。我假设如果您正在使用F# TP,则现在正在使用VS 2012。如果是这样,SvcUtil本身的版本可能不同,这可能与问题相关。
特定错误似乎与此处解释的相同,因此您的服务代码中可能存在不完整的注释。

C# GUI和F# TP都使用SvcUtil生成客户端代码。在使用SvcUtil时有两个变量 - SvcUtil本身的版本和传递给它的参数。如果它在VS 2010 C#中工作,但在VS 2012 F#中不工作,则工具的版本、参数或两者都可能不同。找出差异,这将指向您下一步的修复/解决方法。我提供了链接以提示为什么工具可能会失败 - 可能最新版本比以前的版本更严格。 - latkin
我尝试使用2010年的svcutil命令行版本。在编译C#代码时,它会产生相同的错误...看起来它也会生成与2012 cmdline相同的代码。 - Helge Rene Urholm
@MarcSigrist - 你是对的,我之前的评论是不正确的。感谢您指出我的错误,以便未来的读者!我猜早些时候,VS的“添加服务引用”GUI确实使用了svcutil,但自从VS 2008以来就不再是这样了。现在我们在这两种方法之间出现了不一致-令人震惊! - latkin
@user1758475 显然,ASR在内部应用了一些额外的检查和其他功能,这些功能对svcutil来说是未知的。因此,您不能“强制”svcutil在所有方面都像ASR那样运行。此外,即使您可以这样做,这也没有帮助,因为类型提供程序在内部访问svcutil。解决问题的唯一方法是编写自己的类型提供程序(基于什么,如果svcutil不够好?),或者等待未来更稳定版本的官方WsdlService类型提供程序(可能重新实现ASR的某些部分)... - Marc Sigrist
太糟糕了,当时这是一个认真的尝试去使用它。当然我可以用传统的方式生成它,然后再在F#中使用那个库,但那样的话我还不如留在C#中编写一些普通的单元测试等等...不能说我喜欢它!;-) - Helge Rene Urholm
显示剩余3条评论

0

我无法解决这个问题...

我已经做了以下几点:

  1. 使用普通设置运行svcutil:svcutil http://some.address/some/path.svc
  2. 使用更多选项运行:svcutil /r:“C:\Program Files(x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5\System.dll”/r:“C:\Program Files(x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5\System.Data.dll”http://some.address/some/path.svc

这确实在 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时它不是默认使用的(至少根据文档是这样的)。

另一方面,我认为文档还说,如果程序集在GAC中,它应该使用它们。那么我如何验证它们是否存在,或者如果不存在,如何将它们加载到程序集中?

在版本4.5的System.dll上运行gacutil -i System.dll会出现以下错误:

向缓存添加程序集失败:尝试加载格式不正确的程序。

这是64/32位问题吗?(我在64位Windows上,如果有任何相关性)

或者换句话说,我的问题是:当我无法通过WsdlProvider部分直接添加引用时,如何使System.dll和System.Data.dll成为运行svcutil时的引用之一?

我非常确定它没有使用System.dll,因为如果我向wsdlprovider添加collectiontype参数:

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

它还报告了以下问题:

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

如果引用了System.dll,这个问题应该可以直接解决(我想)。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接