【问题标题】:Why is my use of a generic method in a code-behind class resulting in a dynamic compilation exception?为什么我在代码隐藏类中使用泛型方法会导致动态编译异常?
【发布时间】:2016-05-02 19:42:06
【问题描述】:

对我正在开发的旧版 ASP.Net Web 表单应用程序进行一些更改后,每当我尝试访问该应用程序的页面时,都会收到以下异常。

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\MyApplication\bdb24adf\eb592999\App_Web_mypage.aspx.cdcab7d2.dc1wid-d.0.cs(148):错误 CS0012: “MyDataModelClass”类型是在未引用的程序集中定义的。您必须添加对程序集 'MyDataModelAssembly, Version=40.0.0.30, Culture=neutral, PublicKeyToken=7ca3fb5049101832'的引用

经过数小时的故障排除后,我终于将问题缩小到我添加到基础页面类的方法,应用程序中的所有页面都从该类派生。叫它MyBasePageClass

protected T CreatePlaceholder<T>(T item) where T : MyDataModelClass, new()
{
    return new T { TemporaryIdentifier = item.TemporaryIdentifier };
}

当我注释掉那个方法时,异常消失了,一切都按我的预期工作。如果我在 web.config 文件中添加程序集引用,此异常也会消失。奇怪的是,当我更改对 Copy Local = true 的引用时,这也会使异常消失。

这不是第一次将 MyDataModelClass 合并到应用程序中。它几乎在每个代码隐藏文件中的许多地方使用。但是由于某种原因,将其用作类型约束是 .Net 无法处理的。

我只能想象它与泛型的性质有关,但我不知道那可能是什么。我不是第一个尝试过这个的人,但我在 SO 或其他任何地方都找不到任何关于它的信息。会不会和 IIS 的配置方式有关?

更新:

MyDataModelAssembly 确实安装在 GAC 中。这是 gacutil /l 的输出:

全局程序集缓存包含以下程序集: MyDataModelAssembly,版本=40.0.0.30,文化=中性,PublicKeyToken=7ca3fb5049101832,处理器架构=MSIL

【问题讨论】:

  • 为什么投反对票?
  • 我很想知道谁一直拒绝投票这个问题。对问题进行上下投票的整个目的是使经过充分研究的困难问题可以上升到顶部,而质量差的问题可以下降到底部。考虑到这个问题似乎没有人有好的答案,所以它需要上升到顶部。

标签: c# asp.net .net generics iis


【解决方案1】:

编辑 2: 这看起来像是您的问题的解决方案:Strange Error - CS0012: The type x is defined in an assembly that is not referenced

但没有真正解释原因。


编辑:

由于您的程序集在 GAC 中,它应该可以找到它并且不需要复制本地。

确保 GAC 中的版本是它正在寻找的版本。您可以使用Gacutil 检查 GAC 中的内容。在我的机器上,gacutil.exe 位于“C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools”中,但它可能在您机器上的其他位置。找到它后,从命令行运行它:

gacutil /l MyDataModelAssembly

gacutil 输出的版本和公钥令牌必须与您在错误消息中看到的一致。


必须将定义 MyDataModelClass 的程序集 DLL 复制到 IIS 运行应用程序的位置。

“复制本地”设置告诉 Visual Studio 将 DLL 复制到编译输出路径(这可能是 IIS 运行应用程序的位置)。对于不在 GAC 中的任何程序集,您需要将 Copy Local 设置为 true。

【讨论】:

  • 这个程序集在 GAC 中。
  • 为什么只有在添加泛型方法时才会出现这种情况?这不是类中唯一引用 MyDataModelClass 的地方。
  • 在使用引用的代码实际运行之前,您不会收到错误消息。因此,您使用该类的其他地方可能还没有运行。
  • 尚未运行任何代码。当 IIS 尝试编译任何 .aspx 文件时会发生此异常。
  • 我应该说它会根据需要加载程序集。它如何定义“根据需要”,我不确定。但可以肯定地说,如果您想在项目的任何位置使用该类,则 IIS 需要访问 DLL,这意味着将 Copy Local 设置为 true。
【解决方案2】:

The type 'MyDataModelClass' is defined in an assembly that is not referenced. You must add a reference to assembly 'MyAssembly, Version=40.0.0.30, Culture=neutral,

在您的项目中,您实际上是否有对定义该类的任何程序集 (DLL) 的引用?错误认为你没有。

通过在此处添加 DLL 并将其设置为复制本地来修复它:

【讨论】:

  • 是的,项目中有引用。该应用程序在 Visual Studio 中构建得很好。当 IIS 在提供页面时获取它时会发生编译错误。
  • 确保您也将其设置为复制到 IIS 目录(“复制本地”)。 DLL 必须彼此具有相同的相对结构 - 代码不够聪明,无法找到不合适的缺失 DLL。
  • 如果不包含该通用方法,它就可以正常工作。该程序集安装在 GAC 中。
  • 如果您的自定义程序集在 GAC 中,那么这将完全改变您的问题。
  • 怎么样?异常消息与定位程序集无关。它抱怨没有引用程序集,即使它显然是。 (否则解决方案将无法构建。)
猜你喜欢
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多