I have an aspx page that used a method in a class in the App Code folder, doSomething(int[] x)
. I changed the function definition to use an IEnumerable instead of an array: doSomething(IEnumerable<int> x)
. Next, I precompiled the web site, using "allow web site to be updatable", and published the new App_Code.dll. Now, the precompiled version of the page gives a Server error at runtime: "Method not found".
If I also publish the DLL generated for the page, "App_Web_[page].aspx.[random].dll", it works. So it appears the signature of the function is embedded in the compiled page somehow…? Why is this, and is there a way to avoid this problem when changing existing code?
I'd hate updating all my page DLLs whenever I change code in my common classes.
When a page is compiled it looks at all the method signatures and essentially locks them down. If you change the signature of a method being called, then the page will not be able to locate it until it is recompiled.
For example let's say you have a class like
public class Dog {
public void Walk(Int32 distance) {
/// blah blah
}
}
and you call this in a page code behind:
protected void MyButtonClick(....) {
Dog d = new Dog();
d.Walk(3000);
}
When this compiles down the page will expect a walk method with an Int32 signature.
Now, let's say we change the walk method in the Dog class to:
public void Walk(Int16 distance) {
// blah blah
}
(yes, stupid change but it highlights the issue). At this point the page will not be able to locate a Walk method that takes an Int32 parameter and so will blow up as it should.
It may seem nice to just deploy the one assembly you think you need, but the fact of the matter is there could be any number of changes that occurred in the code so this is a seriously bad practice.
It is much better to make sure the entire project is consistent. Even larger websites don't take that long to deploy.
Of course,I think that using web site projects are bad practice in and of themselves anyway. Deploying uncompiled code to the server (really bad), VS searching your drive to update references in the project even when you have explicitly told it which assembly to use (usually unexpected, never good), having all the main code in a common app_code folder (limiting), etc. I could go on and on here...
If it's a web application then you need to recompile everytime you change server side code - does not matter if it's in a separate assembly or in a App_Code folder of your web app.
Only website (not web application) allows you to change code without recompiling.
You need to recompile because your page was published and output to a dll in the bin folder. This dll is looking for a method with a signature of:
doSomething(int[])
And it isn't there any more. When you publish, update everything, every time.
I believe the 'updatable' flag permits you to update your aspx code (i.e. the markup), but the codebehind files will have been compiled away.
The following kinds of changes may cause run-time exceptions:
Changing the signature of a method, or the type of a property. If the affected member is referenced by an already-compiled page, an exception will be thrown. Some signature changes would not cause compile or run-time errors if the whole site is recompiled. For example, the code Response.Write(ClassA.MethodA() in an .aspx page will compile and run fine whether MethodA returns an int or a short. But if the .aspx page is already compiled and you change the return type of MethodA from int to short without recompiling, a runtime exception will be thrown because the compiled code expects the int signature.
From http://msdn.microsoft.com/en-us/library/ms366723.aspx#sectionToggle5
来源:https://stackoverflow.com/questions/9127165/why-do-i-need-a-recompiled-page-when-a-method-used-by-it-changes