F# Asp.Net CodeDom 提供程序选项问题

3
我正在使用F#在IIS 7上创建一个ASP.NET MVC应用程序。当我尝试从浏览器运行它时,遇到了一个包含以下内容的怪异错误页面:
[ArgumentNullException: Value cannot be null. Parameter name: dictionary] System.Collections.Generic.Dictionary`2..ctor(IDictionary`2 dictionary, IEqualityComparer`1 comparer) +12700827 System.Web.Compilation.CompilationUtil.CreateCodeDomProviderWithPropertyOptions(Type codeDomProviderType) +84 System.Web.Compilation.CompilationUtil.CreateCodeDomProviderNonPublic(Type codeDomProviderType) +16 System.Web.Compilation.AssemblyBuilder..ctor(CompilationSection compConfig, ICollection referencedAssemblies, CompilerType compilerType, String outputAssemblyName) +469 System.Web.Compilation.CompilerType.CreateAssemblyBuilder(CompilationSection compConfig, ICollection referencedAssemblies, String generatedFilesDir, String outputAssemblyName) +127 System.Web.Compilation.BuildProvidersCompiler.ProcessBuildProviders() +675 System.Web.Compilation.BuildProvidersCompiler.PerformBuild() +46 System.Web.Compilation.ApplicationBuildProvider.GetGlobalAsaxBuildResult(Boolean isPrecompiledApp) +11321455 System.Web.Compilation.BuildManager.CompileGlobalAsax() +50 System.Web.Compilation.BuildManager.EnsureTopLevelFilesCompiled() +872
我通过Reflector查找方法以获取更多上下文信息,发现它在第一行出错了。
private static CodeDomProvider CreateCodeDomProviderWithPropertyOptions(Type codeDomProviderType)
{
IDictionary<string, string> providerOptions = new Dictionary<string, string>(GetProviderOptions(codeDomProviderType));
//Snip
}

这让我相信,我在Web.config中为F# CodeDom指定的propertyOptions不正确。但是,如果我将它们删除,我会收到相同的错误。

<system.codedom>
 <compilers>
  <compiler language="F#;f#;fs;fsharp" extension=".fs" warningLevel="4" 
            type="Microsoft.FSharp.Compiler.CodeDom.FSharpAspNetCodeProvider, 
                  FSharp.Compiler.CodeDom">
    <providerOption name="CompilerVersion" value="v4.0"/>
    <providerOption name="WarnAsError" value="false"/>
  </compiler>
 </compilers>
</system.codedom>

有没有关于纠正这个错误的想法?
3个回答

4

这是关于VS2010 Beta2中ASP.NET的一个漏洞(已经被修复,所以在下一版本中将正常工作)。它会影响任何第三方CodeDOM提供程序,我认为没有任何解决方法。


这个 bug 有任何文档记录吗? - statenjason
我只有微软内部的电子邮件/错误信息,不知道是否有公开的Connect错误。我找到了一些对话,说提供"CodeDomProvider.FileExtension"可能会解决这个问题。我对ASP.Net几乎一无所知,但也许对你有意义? - Brian
感谢提到FileExtension。我进行了一些调查,发现可用的文件扩展名是硬编码的,并不包括"fs"。我在我的回答中详细解释了这个问题。 - statenjason

3
我找到了问题的原因。
Microsoft.FSharp.Compiler.CodeDom.FSharpAspNetCodeProvider.FileExtension 是硬编码为“fs”。
在 System.CodeDom.Compiler.CodeDomCompilationConfiguration..ctor() 中,为每个允许的语言创建 CompilerInfos。在此期间未找到 FSharp 的 CompilerInfo。
internal CodeDomCompilationConfiguration()
{
this._compilerLanguages = new Hashtable(StringComparer.OrdinalIgnoreCase);
this._compilerExtensions = new Hashtable(StringComparer.OrdinalIgnoreCase);
this._allCompilerInfo = new ArrayList();
CompilerParameters compilerParams = new CompilerParameters();
compilerParams.WarningLevel = 4;
string codeDomProviderTypeName = "Microsoft.CSharp.CSharpCodeProvider, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
CompilerInfo compilerInfo = new CompilerInfo(compilerParams, codeDomProviderTypeName);
compilerInfo._compilerLanguages = new string[] { "c#", "cs", "csharp" };
compilerInfo._compilerExtensions = new string[] { ".cs", "cs" };
compilerInfo._providerOptions = new Dictionary<string, string>();
compilerInfo._providerOptions["CompilerVersion"] = "v4.0";
this.AddCompilerInfo(compilerInfo);
compilerParams = new CompilerParameters();
compilerParams.WarningLevel = 4;
codeDomProviderTypeName = "Microsoft.VisualBasic.VBCodeProvider, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
compilerInfo = new CompilerInfo(compilerParams, codeDomProviderTypeName);
compilerInfo._compilerLanguages = new string[] { "vb", "vbs", "visualbasic", "vbscript" };
compilerInfo._compilerExtensions = new string[] { ".vb", "vb" };
compilerInfo._providerOptions = new Dictionary<string, string>();
compilerInfo._providerOptions["CompilerVersion"] = "v4.0";
this.AddCompilerInfo(compilerInfo);
//Snip
}

System.CodeDom.Compiler.CodeDomProvider.GetCompilerInfoForExtensionNoThrow中,将FileExtension与_compilerExtensions进行比较。对于"fs"的情况,返回null给System.CodeDom.Compiler.CodeDomProvider.IsDefinedExtension,然后返回false给System.Web.Compilation.CompilationUtil.GetProviderOptions,该方法返回了导致ArgumentNullException的null值。

感谢@Brian指引我正确的方向。


虽然我相信硬编码扩展名的方法有其奇怪之处,但这还是相当离奇的。 - AboutDev

0

也许可以通过在 web.config 中指定更多的信息来解决 Brian 注意到的 bug:

type="Microsoft.FSharp.Compiler.CodeDom.FSharpAspNetCodeProvider, 
      FSharp.Compiler.CodeDom,
      Version=1.9.7.8, 
      Culture=neutral, 
      PublicKeyToken=a19089b1c74d0809"

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