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