当它使用的方法发生变化时,为什么需要重新编译页面?

时间:2012-02-03 10:30:15

标签: c# asp.net web-site-project

我有一个aspx页面,它在App Code文件夹doSomething(int[] x)中的类中使用了一个方法。我将函数定义更改为使用IEnumerable而不是数组:doSomething(IEnumerable<int> x)。接下来,我使用“允许网站可更新”预编译网站,并发布新的App_Code.dll。现在,页面的预编译版本在运行时出现服务器错误:“找不到方法” 如果我还发布了为页面生成的DLL,“App_Web_ [page] .aspx。[random] .dll”,它可以正常工作。所以看来函数的签名是以某种方式嵌入到编译页面中的?为什么会这样,有没有办法在更改现有代码时避免这个问题? 每当我更改公共类中的代码时,我都讨厌更新所有页面DLL。

4 个答案:

答案 0 :(得分:3)

编译页面时,它会查看所有方法签名,并基本上将其锁定。如果更改被调用方法的签名,则在重新编译之前页面将无法找到它。

例如,假设您有类似

的类
public class Dog {
  public void Walk(Int32 distance) {
    /// blah blah
  }
}

你在后面的页面代码中调用它:

protected void MyButtonClick(....) {
  Dog d = new Dog();
  d.Walk(3000);
}

当这个页面编译时,页面会出现一个带有Int32签名的walk方法。

现在,假设我们将Dog类中的walk方法更改为:

public void Walk(Int16 distance) {
  // blah blah
}

(是的,愚蠢的改变,但它突出了问题)。 此时,页面将无法找到采用Int32参数的Walk方法,因此会爆炸。


仅部署您认为需要的一个程序集似乎很不错,但问题是代码中可能发生任何数量的更改,因此这是一种非常糟糕的做法。

确保整个项目的一致性要好得多。甚至更大的网站也不需要那么长的时间来部署。

当然,我认为使用网站项目无论如何都是不好的做法。将未编译的代码部署到服务器(非常糟糕),VS搜索您的驱动器以更新项目中的引用,即使您明确告诉它使用哪个程序集(通常是意外的,永远不会好),将所有主要代码放在一个共同的app_code文件夹中(限制)等等。我可以继续这里......

答案 1 :(得分:1)

如果它是一个Web应用程序,那么每次更改服务器端代码时都需要重新编译 - 如果它位于单独的程序集或Web应用程序的App_Code文件夹中,则无关紧要。

只有网站(不是网络应用程序)允许您更改代码而无需重新编译。

答案 2 :(得分:0)

您需要重新编译,因为您的页面已发布并输出到bin文件夹中的dll。这个dll正在寻找一个签名为:

的方法
doSomething(int[])

它已经没有了。发布时,每次都要更新所有内容。


我相信'updatable'标志允许你更新你的aspx代码(即标记),但代码隐藏文件将被编译掉。

答案 3 :(得分:0)

  

以下类型的更改可能会导致运行时异常:
  更改方法的签名或属性的类型。如果   受影响的成员由已编译的页面引用   异常将被抛出。某些签名更改不会导致   如果重新编译整个站点,则编译或运行时错误。对于   例如,.aspx页面中的代码Response.Write(ClassA.MethodA()   无论MethodA返回int还是short,都将编译并运行正常。   但是如果.aspx页面已经编译并且您更改了返回   MethodA的类型从int到short而不重新编译,运行时   将抛出异常,因为编译的代码需要int   签名。

来自http://msdn.microsoft.com/en-us/library/ms366723.aspx#sectionToggle5