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

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

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

例如,假设您有类似的课程

 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文件夹中( 限制 )等我可以继续……

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

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

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

 doSomething(int[]) 

它不再存在了。 每次发布时,都会更新所有内容。


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

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

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