When is <Compilation> used in ASP.net - asp.net

I'm having some trouble setting the ExecutionTimeout element in my applications web.config.
My page is making a lengthy webservice call and times out after 110 seconds. (the default I believe). I set the value to 220, and make sure the compilation debug=false.
Does the compilation setting refer to when IIS/ASP.net compiles the ASPX pages when a client requests them, or does it refer to the visual studio compile process there the assemblies are created.
Would using an assembly built using debug in visual studio still allow the above settings to work?

IIS does not compile aspx pages when people request them. If you have a 'web application project' in VS, you compile all of your code behinds and other class files before you deploy. If you have a 'web site project' in VS, then the web server compiles your app on first request only. After either one of these happen, the application is not compiled again until you make a change.
With that information in mind above, this is when the compilation debug = true | false comes into play. Having debug = true, you get some pretty detailed information back on errors and other events but it can make your app run slower as debug symbols are inserted into the .dll and overall, it is not optimized for performance. By setting debug = false, you don't get quite the same level of error reporting, but you do get your performance gains back.
If you build in VS, it will build according to the settings in the web.config unless it is an external .dll/class project that you are including. If that is the case, the web.config settings mean nothing to that .dll and will run regardless of what combination of debug = false|true you have on those two projects.

Compilation tag is used to add referenced libraries for compilation by IIS or Visual Studio and to specify debug and batch compilation modes.
Speaking of debug attribute, here's good article with all the details in Milan Negovan blog.
And about compilation itself.
There are 3 modes of compilation. They are fully described in MSDN Overview.
By default web application uses updateable precompilation: all .cs files are compiled into one assembly, but all pages, controls and master pages are compiled on demand into new derived class.
Web Site project uses in-place compilation by default.
And non-updateable full precompilation must be specified explicitly. And here when compilation tag comes in. If batch="true" then all pages in application will be compiled upon first request to any page. This moves us to yet another story about big applications :)
Note that there are some other specifics in compilation model, look into ASP.NET Precompilation Overview if you really need this.

IIS compiles ASPX pages (and ASCX UserControls, ASHX, ASMX, ...) the first time they are requested. It also dynamically compiles:
Code in the App_Code folder
Code in code-beside pages for a website project
The compilation element in web.config refers to this compilation.
If you are using a Web Application Project in Visual Studio, your ASPX pages will have a code-behind file. This is compiled into a DLL when the project is built in Visual Studio, and won't be affected by the web.config compilation element.

Related

Which dll files of ASP.NET web application does IIS load?

I couldn't find any information about it. Does anybody know whether IIS load all dlls in bin directory of web application or all dlls in any directory or maybe only directories referenced by project (in this case how it determines which dll is "master")?
I've just had a situation where someone didn't remove all files from web application directory before deploying new version, while some dll was renamed. This redundant dll was in bin directory of MVC 4 web application.
As an experiment I made a new ASP.NET Webforms project, and deployed it to IIS. I then made a 2nd .net class library, and copied the .dll file to the web app's \bin folder (the class library is not referenced or used anywhere in the ASP.NET app).
I started up SysInternals ProcMon, recycled the app pool and web site in IIS, and requested the site in a browser.
w3wp.exe does indeed read the class library .dll file on first page request.
This MSDN page also states:
You can store compiled assemblies in the Bin folder, and other code anywhere in the web application (such as code for pages) automatically references it. A typical example is that you have the compiled code for a custom class. You can copy the compiled assembly to the Bin folder of your Web application and the class is then available to all pages.
Assemblies in the Bin folder do not need to be installed in the Global Assembly Cache (GAC). The presence of a .dll file in the Bin folder is sufficient for ASP.NET to recognize it.
Which does seem to imply that ASP.NET will reflect over the assemblies it finds in \bin and automatically load them.
Interestingly, even if you put a non-.net file (I copied twain.dll from C:\Windows) into your ASP.NET bin folder, those files are also read. The runtime seems to just ask the filesystem for \bin\* and loops over the files to check for .NET assemblies to load.
I also noticed that if you add this to your web.config file:
<system.web>
<compilation targetFramework="4.5">
<assemblies>
<clear />
</assemblies>
</compilation>
Then the page will no longer run, with the error
Could not load type 'WebApplication1.Global'.
So it seems that the runtime no longer loads those classes from the assemblies. However, the runtime still reads the non-referenced console application .dll and non-.net assembly twain.dll off the drive.
So, the answer comes down to what you mean by "loads all dlls" ... If you mean makes available in the runtime, then the answer is sort-of "no" if you specify your own system.web | compilation | assemblies but the default is to load all. But if you mean what files are physically read, then "yes".
It doesn't load any DLLs automatically.
Every DLL it loads is directly related to a request. First, Global.asax is compiled (which may load some DLLs from bin). Then, whatever HTTP modules and HTTP handlers are defined in web.config (there's some overlap with the previous step). Then the final aspx/asmx/... Some others might go for the ride as part of the configuration or something like that, but all the DLLs that are loaded are always loaded explicitly.
Thus, there is no "master" DLL. web.config, Global.asax and the actual requested file are the ones to decide what's actually going to happen. If you need to have a particular DLL loaded (and you don't simply have it referenced), you need to do it yourself.
EDIT:
Since this is a bit complicated, let me expand a bit.
The main thing to keep in mind here is that ASP.NET is always dynamically compiled - at least to an extent. At the very least, you always have to compile Global.asax - no way around it. Now, dynamic compilation in ASP.NET has an important feature - it's out-of-process (at least for the legacy compiler - I'm not sure about Roslyn+). So whatever the compiler does to find references etc., doesn't actually reflect what's loaded to the worker process itself - and to your application domain in particular.
The dynamic compilation is handled by the BuildManager class on the .NET side - http://referencesource.microsoft.com/#System.Web/Compilation/BuildManager.cs,fb803c621f3806a8. Since you asked about a "master DLL", the most relevant bit would be the code that handles Global.asax compilation, which is one of the starting points of any ASP.NET application. The very initial compilation is handled by the EnsureTopLevelFilesCompiled method. Looking through the code, you can easily see the first steps:
CompileResourcesDirectory();
CompileWebRefDirectory();
CompileCodeDirectories();
...
CompileGlobalAsax();
Most of this is slightly different for web sites vs web projects, as well as for pre-compiled sites, but we can pretty much ignore that. Now, the code isn't the simplest code in the world, but basically, it boils down to producing a bunch of assemblies - about one assembly per code directory. Again, this is done out of process - while the compiler has to load the binaries in bin, they are not necessarily loaded into the ASP.NET worker process. Instead, only the necessary references are actually loaded.
The main thing to take from this is that the dynamic compilation will indeed do a lot of resolving to help you (after all, you don't even know the name of the dynamic assembly where your types are compiled, so you can't specify it!) - but that doesn't mean that all the assemblies in bin are loaded in your ASP.NET application domain. The easiest way to check this is to add an empty assembly that isn't referenced anywhere to bin, and then print out AppDomain.Current.GetAssemblies - you will see that while the file was indeed touched during the compilation process, it wasn't loaded into the ASP.NET application domain. You need to bear this in mind if you ever try to implement some dynamic module loading in ASP.NET - you need to load those assemblies yourself.
You can tweak the way the compilation works in your web.config (especially the global one) - for example, by default, all the assemblies in bin are loaded for compilation purposes, but you can use the system.web/compilation/assemblies tag to cherry pick whatever you want.
Yes asp.net loads any dlls present in your bin directory .
I have recently written a blog on this as I ran into an issue with dlls which were not used in my project. Please refer this blog ,trying to discuss couple of other common scenarios as well.
Asp.net loads all dlls in the bin directory.

Best Method for Converting a Web Application into an IIS Website

I have a Web Application and want to move/make it as a IIS website
1. Not Copying the DLL
When I copy every part of the code except the Web Application's built DLL file I come up with an error
"could not load type ..."
2. Copying the DLL
cloning that DLL also shouldn't be practical.
If we copy the DLL so the site will work as expected
but after any changes to code-behind other problems will occur
"... does not contain a definition for btnABC_Click() ...."
What should be our decision or strategy in this case
--
I want to make an IIS-Version of the project because of fixing some addressing-Paths issues
thanks in advance
When the Web site runs, ASP.NET code in your Web page doesn't call the C# code that you've written in your code-behind files. Rather, it calls a compiled version of that C# code that is in the application's DLL file.
So the C# code in the code-behind must be compiled after any change into a new version of what you refer to as the "web application's built DLL".
Otherwise your Web page will refer to an old version of the DLL, hence the errors "... does not contain a definition for ...".
You may want to investigate the walkthrough here: http://msdn.microsoft.com/en-us/library/1y1404zt(v=VS.100).aspx
and read the background material here: http://msdn.microsoft.com/en-us/library/377y0s6t.aspx
as they explain in fine detail what you'll need to do.

Updating a DLL in a Production ASP.NET Web Site bin folder

I want to update a class library (a single DLL file) in a production web application. This web app is pre-compiled (published). I read an answer on StackOverflow (sorry, can't seem to find it anymore because the Search function does not work very well), that led me to believe that I could just paste the new DLL in the bin folder and it would be picked up without problems (this would cause the WP to recycle, which is fine with me because we do not use InProc session state).
However, when I tried this, my site blows up and gives a FileLoadException saying that the assembly manifest definition does not match the assembly reference. What in the world is this?! Updating the DLL in Visual Studio and re-deploying the entire site works just fine, but it is a huge pain in the rear. What is the point of having a separate DLL if you have to re-deploy the entire site to implement any changes?
Here's the question: How can I update a DLL on a production web site without breaking the app and without re-deploying all of the files?
The thing to remember is that there are web sites and web applications as far as Visual Studio and ASPNET is considered.
Web Sites typically have all of the aspx and vb files published to the live server and ASPNET Worker Process recompiles the app every time before presentation.
On the other end is the web application, where all of your code behind files get compiled down to a single DLL file and you simply deploy your aspx pages and you bin folder with the DLL file to production.
There is also a "hybrid" known as "Precompiled Web Sites" (see the link for the official MSDN overview) where you don't have the single DLL layout of a web application, but all the compile work of the website is done for you. There are several "modes" to this depending on your needs.
It seems to me that your error is caused because your site is set up as a web site with some kind of precompilation in place. Using the pre-compiled model is a little more "strict" in that is assumes certain files/signatures are in place. Having an updated version of the DLL file causes a break since the precompilation wants a name and a version of the file.
If possible, your best bet would be to convert to a web application, since you can add the additional DLLs into production without a problem. Otherwise, take a look at this matrix to see what form of precompilation you need for your application.
Look at this SO post, might be what you are referring to. The located assembly's manifest definition does not match the assembly reference
Have a look at your reference. Does it say "specific version = true" ? Set it to false, republish your app (you have to do it once, because now your app is still looking for an assembly with a specific manifest) and try it again.

ASP.NET isn't automatically rebuilding

If you create an ASP.NET Web Site project and run it, you get a blank page. If you go into the default CodeBehind file, add into the Page_Load method throw new Exception();, save the file, and refresh it in the browser (without rebuilding), the server automatically rebuilds the project and the page will error.
I have a project that I am working on now where refreshing the page does not cause the project to be rebuilt (the new aspx files are used but the old DLLs are used with them). What causes this, and how do I correct it?
Is this new project a web application project by any chance? I believe you have to actually build that before changes will be seen.
Web Application Project is a separate type of project that requires all code behind to be build. The resulting dll is build under the bin folder. The code behind files are not used in execution, and is the preffered way of doing it if you don't want to expose your code at the installed web server, and to be sure execution is faster (never compiling in runtime).
When you creatied it as "ASP.NET Web Site", it is NOT a "Web Application Project".
Only code which is in App_Code will be automatically recompiled when it changes. If your code lives anywhere else, then it's part of the pre-built DLL you get when you hit "compile".
You are using the Website model. The pages will be compiled when you access them. Class Library projects in the same solution will not. Hence why you see this behaviour.
By default, the ASPX, code behind and App_Code source files get compiled. If you have a seperate project in the solution (a BLL or DAL perhaps), these will not be updated by simply refreshing the browser.
So to correct it you could do a proper build in Visual Studio, or you could move the class files you want to change into App_Code. Personally I'd stick with the former (actually I don't ever use the Website option- always Web application project).
OK. Have you got 'Edit and Continue' enabled?
MSDN

How to make the process of debugging ASP.NET Sharepoint applications less time consuming?

I'm comparing it Java where you can start your application server in debug mode, then attach your IDE to the server. And you can change your code "on the fly" without restarting the server. As long as your changes don't affect any method signatures or fields you can just hit recompile for a class and the application server (servlet container) will reload the class.
I suppose this is impossible in ASP.NET since all classes are packed into assemblies and you cannot unload/reload assemblies, can you ?
So when you have an .aspx page and an assembly deployed to GAC and your codebehind changes you have to redeploy the assembly and reset IIS. I'm talking about Sharepoint applications in particular and I'm not sure whether you have to do iisreset for private assemblies but I guess you have too.
So the best way to debug aspx pages with code behind I guess would be to get rid of the codebehind for the time of active debugging and move into the page, then when it is more or less working move it back to codebehind. (This would be applicable only for application pages in Sharepoint, site pages don't allow inline code )
How do you approach debugging of your ASP.NET applications to make it less time consuming?
From Matt Smiths blog on how to get F5 debugging with sharepoint. A very cool trick.
Create a web application project in Visual Studio (File -> New -> Project -> ASP.Net Web Application, not File -> New -> Web Site).
Move the .csproj and .csproj.user files, along with the Properties folder, into C:\inetpub\wwwroot\wss\virtualdirectories\, where is the name or number of the web application corresponding to the SharePoint site you'd like to debug on.
Attach the project to an existing solution (e.g. STSDEV project).
Set as startup project (right-click project name, "Set as Startup Project").
Access project properties (right-click project name, "Properties") and click
Under the "Servers" setting, click "Use IIS web server", then enter the URL to the SharePoint web application you want to debug on, e.g. http://mymachine:99.
Yes private assemblies DO NOT require reset of the IIS. So you should just to xcopy new version to the application's Bin directory and refresh the page (e.g. by VS post build event as I did).
But there are some trade offs. You should decrease trust level in application web.config file:
<system.web>
...
<trust level="WSS_Medium" originUrl="" />
...
</system.web>
By the way. I do not suggest to deploy like this. It's just workaround for comfort write-test-debug cycle length.
If you are using the GAC, you can at least do iisapp.vbs /a "App Pool Name" /r instead of iisreset (it's quicker to recycle a single app pool than to restart IIS).
First, develop on a computer running SharePoint. Preferably, this means running Windows Server 2003 on Virtual PC or VMWare. This will let you deploy and debug SharePoint code directly, rather than having to copy files between servers and use the remote debugger.
Use a VS add-in to simplify the process of deployment and debugging. I've been using WSPBuilder but I think there are others out there. WSPBuilder has commands to deploy solutions, package them as WSPs, and attach your debugger to the local IIS process. It won't allow you to add/remove assemblies on the fly, but you can set breakpoints and run code through the Immediate window in VS.
Depending on how your production server is configured, it's usually a good idea to develop on a server with full/trust security settings, including disallowing code blocks in ASPX files. This makes debugging a little more difficult, but it reduces the number of nasty surprises you'll have when your code is finally deployed to production.
And you can change your code "on the fly" without restarting the server
You can accomplish this with ASP.net if you make a Web Site project (as opposed to a Web Application Project). Using a Web Site project, you can post changes to code-behinds without having to refresh anything on the server, and the server does the compile work for you on all code changes. See here for more info on this.
This should also solve your difficulties with deploying the assembly to the GAC. As the server handles all compilations for Web Site projects, you wont have to redeploy any assemblies when changing files.
Use an automated testing framework (NUnit) to write integration tests. This won't work for everything, but of course, it depends on what you're testing.
If you also have TestDriven.NET installed, you can run individual tests with the debugger. This has been helpful.
WSPBuilder Extensions has a "deploy to GAC" shortcut, unfortunately it never works for me. But it's a really quick way to code->compile->test.
If you're not using WSPBuilder Extensions, you can instead open a command prompt and run
gacutil /u yourassemblynamegoeshere
gacutil /i yourdllgoeshere.dll
If you do this often, you can put it in a post-build event or in a batch file. Also, I'm unclear whether the gacutil /u (to remove the DLL first) is necessary.
What it seems like you're trying to do is tell Sharepoint "When I start debugging in Visual Studio, use the version of the DLL that was compiled in the project's /bin/debug directory instead of the version of the DLL that is registered in the GAC." I haven't solved that problem, but here is how I debug Sharepoint.
A developer machine is Win2008, IIS 7, MOSS 2007, VisStudio 2008, and WSP Builder installed. Inside VS2008, a button is added to attach to w3p.exe process, Andrew's HOWTO attach to w3p
The solution file has two projects:
* First project is the .WSP that deploys all the app pages, including the DLL. Use WSPBuilder menu items for handling the .WSP creation and deployment.
* Second project is for the DLL behind the pages.
If you want the DLL to be copied to the GAC regularly, add a post-build event to the DLL's project that copies from /bin/Debug to the GAC. But, these days, I find I have just been recompiling the solution and then deploying the .WSP using the menu items, and then starting up the debugger using the button. It takes me an F-key and 3 clicks and about a minute for most of my projects, but I suppose it could be quicker.

Resources