Single code-behind to override class in the web project dll? - asp.net

Is there a way to deploy changes to a single code-behind file when using a "web project" (i.e. the web project dll is in the bin) without deploying the whole dll? Will the single file override the class in the dll if placed in the bin?

No, there isn't. Since it is part of the compiled DLL, you need to recompile and redeploy.
Putting the file in the bin folder will do nothing.
If you have a web farm, you could take some of the servers offline, update the application, put them back online and do the same with the remaining servers, so no downtime occurs (of course, you need to ensure that changes to shared code and systems can work with both versions of your code).

Related

Remove .cs file in published asp.net webforms project

In the old asp.net project, there is a published .cs file in one of the folders. When I update the site, I update the .dll files, but this file is never updated. When I delete this .cs, the site does not work. How do I delete this file?
Are you using a asp.net web site applcation to publish, or are you using a asp.net web site?
As a general rule, if you using asp.net web site applcation, then the source code files are NOT required to be up-loaded.
However, you left out one big detail. Where is that cs file? While a asp.net web site will attempt and does pre-compile all code, ONE BIG exception to this rule exists.
That is the folder app_code. That folder is in fact compiled by IIS, and as a result, if that file is in that folder, it will have to be included in your publish.
In fact, when I started using the newer Roslyn compiler (I liked it VERY much for allowing me to have longer free text such as SQL in the code as strings).
However, IIS did not and does not have Roslyn compile by default. And my code was breaking.
So, as a result, I simple create my own folder called MyCode. And you could do the same. Note that each code module (vb.net) or static class for your general shared code routines do have to be marked manually as to compile.
eg this:
So, if your .cs file is in app_code, then you can move it out, drop it into a folder you create, and set the file build action to compile, and of course do not copy.
However, and this is a HUGE big "if". If your deployment model is web site as opposed to web site applcation, then this will not work, since IIS is doing your compile after deployment, as opposed to pre-compiling the code BEFORE deployment.
So, you are in luck if your .cs file is (or was) in app_code, since then as noted, you can move that out of app_code, and in properties set the file to be compiled, but not deployed. This as noted will only work if you deploying as a asp.net web site applcation as opposed to a asp.net web site.

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.

How to create and run an ASP.NET website in an installed application's bin directory

Our application is composed of mixed C# / managed C++ CLI / native C++ assemblies & DLLs.
We have a wrapper assembly that exposes the application's API.
FOR EXAMPLE...to create new console applications that use the API, you must reference that assembly, and also set the console application's output directory to the BIN directory of our installed application. ( due to the use of reflection, etc., everything must stay in the app's BIN directory and output to that directory, you cannot do a copy local of just the one assembly or nothing works )
My issue is when creating an ASP.NET web forms application (nothing to do with the console app), I would like to use that assembly, so I need the web application to "live" in our application's BIN directory.
When I try that errors occur due to ASP.NET trying to preload every single assembly in that BIN directory.
Can someone provide instructions on how to get this to work? I've spent hours now on every combination of referencing assemblies, copying them all, and trying to use LoadFrom.
Without seeing the construction of this it's hard but ...
Bin referencing
Create a web application and reference the necessary dll from the web site via bin references
Right click the web application, select the browse option and pcik the dlls you need to reference. Select copy local to true so you get the dll copied through to the web application so you aren't forever dependent on the console app being exactly where it needs to be in relation to the web app.
Not a solution I would necessarily go with though - it seems like the arcitecture of the system is a little off. Cross you have to bare etc...
OR
GAC referencing
the dlls that you need to reference from the console app - strongly name them and put them in the GAC (global assembly cache). Both apps will be able to see them then.
Copy over the dll
I guess there is another solution around adding a post build step to the console app that reruns a batch file that will copy over the dlls into the web app. I think that's going to be pretty much the same as the bin reference though really.
Probing element
You could use a <probing> element in your web.config to instruct the CLR to search for other directories for assembles (it normally just does the GAC and bin (a simplification to be fair is that) ). This is going to enable you to reference your API folder - but only if it is under your application path. Although someone here has used an NFTS junction to get around this.
More info here
In fact this answer gives a lot more detail about this kind of thing
How do I reference assemblies outside the bin folder in an ASP.net application?
And good luck

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 Web Deployment Projects: getting rid of .compiled files

I'm using a Web Deployment Project in Visual Studio 2008 in order to prepare my ASP.NET application (ASP.NET web application, not ASP.NET web site) for being copied to several servers. I have to copy the files on local staging servers, on different servers via FTP and sometimes I have to fetch them from customers' servers.
So, it would be nice to have all files for deployment in a compact form without the necessity of doing a lot of comparing between source and destination. Web deployment projects have this nice feature: compile all your aspx and ascx files into a single (additional) assembly.
I somehow found out how to get rid of aspx placeholder files on the server, now I'd like to know if there is a (maybe self-made) way to get rid of these .compiled files.
From Rick Strahl's blog:
The .Compiled file is a marker file
for each page and control in the Web
site and identifies the class used
inside of the assembly. These files
are not optional as they map the ASPX
pages to the appropriate precompiled
classes in the precompiled assemblies.
If you remove the .Compiled file, the
page that it maps will not be able to
execute and you get a nasty execution
error.
Anybody out there with a creative idea, maybe using a module/handler which intercepts the check against the .compiled files in the bin folder?
The .compile file comes from pre-compiling on deployment. So you basically have 3 options:
Keep the .compiled file
Don't pre-compile and deploy source code
Turn this in to a Web Application instead of a Web Site and compile as an assembly
I have run in to the same problem myself. I actually choose #1 in most cases when dealing with deployment of Web Sites, but on the rare occasion when I know I am going to have to maintain the site for an extended period of time, I take the time to upgrade it to a Web Application.
I don't like the .compiled files either, but nobody gets hurt if they're there. So why bother?
You might want to take a look at Virtual Path Providers (KB how to here) in ASP.NET.
Credit for this suggestion must go to Cheeso and his self answered question here:
Can I get “WAR file” type deployment with ASP.NET?
I don't know about the .compiled files, but you could set up your servers to update their files with subversion instead of manually copying the files when you compile.
So you would compile the files using the Web deployment project (not into a single assembly), put them in a repository you created for this purpose, and on each server, just do an svn update to fetch and compare the files automatically.
I know it's not what you asked for directly, but it may be a path to explore.
Add "Exclude Filter" to your deployment project:
In the Deployment Project.
Right Click on Content Files.
Click on "Exclude Filter".
Add "*.Compiled"
click OK.
and thats it.
I remember at the days when I cant do Web Application with VWD Express, I use nant script to compile the project into a single dll and deploy, that would work (so I dont need the full VS to do dll deployment too), so if you really don't want to mess your project to Web Application, maybe this is a path to check too.
You can get rid of the .compiled files by using the aspnet_merge tool with the -r option.
Removes the .compiled files for the main code assembly (code in the App_Code folder). Do not use this option if your application contains an explicit type reference to the main code assembly.
If you publish your code as updateable (in publish settings) these files are generated. Uncheck that value and republish. This is an old question I know, but no answers are clearly defined for this here.

Resources