I have an ASP.NET application which is adding up .NET assembly in its reference. The assembly is a private assembly and it has a config file with some keys under <AppSettings>.
Now the problem is when I am debugging my ASP.NET application the assembly is not loading the app.config file.
I observed that under the property of referenced assembly I have Copy Local=true.
Can anyone please help or point out if i am missing some basics?
You need to collect all pertinent settings into the web.config file of the main ASP.NET application. Only the config file of the running application (be it web or desktop) is loaded automatically.
Look up some articles on how config files work in the .NET environment to learn the basics of what is and isn't loaded, it'll definitely help you avoid headaches like this in the future.
Alternatively, if you know the name of your assembly's config file you can add a file attribute to your <AppSettings> element, pointing to that file if it's copied to the same directory as the web.config is in.
<appSettings file="privateassembly.config">
Please note that any appsetting with the same name declared in the web.config will be overridden by the privateassembly.config. Also note that any change to privateassembly.config (while the ASP.NET application is running) will not reset the application pool and thus will not be loaded into the AppDomain.
Related
I need to find a way to configure the manifest of a website in order to change the version number or add a redirection binding of a referenced assembly on production. When it comes to windows applications its pretty easy to find the configuration file attached to the exe file and do the desired changes, but i cant seem to find it in a web site (not a web application although i think its the same there). I checked the web config but the assembly reference was not specified there. Does anyone know where to look?
I have a Referenced Assembly where CopyLocal = True, The file is present in the bin folder, but it is not being copied to Temporary ASP.NET Files when I run the solution from Visual Studio
The error message is the usual:
An error occurred loading a configuration file: Could not load file or assembly 'MyNamespace.Configuration, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
Solution / Actual Cause
There were a number of problems:
Problem 1: In order to load a configProtectedData Provider, at least in my environment - the assembly must be in the GAC.
The reason for this was revealed by the fusion logs. Although my web app could locate the assembly in the bin folder - the web server (IIS Express) also needs to load it and it was this part that was failing. Since the web server has no knowledge of my bin folder, the only place it can possibly get the file from is the GAC. Fusion shows that IIS Express was having-a-go at looking in Temp ASP .Net folders but I think that this might be some kind of fallback and in my case the shadow copy was indeed copying the assembly but to a different location (Temporary ASP.NET Files\root\4f27e88a\bfcf2f79\assembly\dl3\06324d99\85ff3c73_1943cf01) that IIS Express didn't know to look for.
Problem 2: Once I had the assembly in the GAC properly, (surprise) Typo. I had the class name wrong in the "type" attribute
The thought process to get to the Solution
First: Follow Ivan Niktin's debugging process, Second Fusion Logs are your friend
It makes sense that it is trying to load it from Temporary ASP.Net Files as this is an MVC Web Application.
What doesn't makes sense is that the Temporary ASP.Net Files location that is being searched is empty. If I add the assembly to the GAC then it loads fine, but this is not an option for my deployment scenario.
The Fusion Log shows as the first path searched:
LOG: Attempting download of new URL file:
///C:/Users/Rob/AppData/Local/Temp/Temporary ASP.NET Files/root
/4f27e88a/bfcf2f79/MyNamespace.Configuration.DLL
The other paths are:
.../MyNamespace.Configuration.DLL
.../MyNamespace.Configuration/MyNamespace.Configuration.DLL
.../MyNamespace.Configuration.EXE
.../MyNamespace.Configuration/MyNamespace.Configuration.EXE
When I view the content of the folder that is being searched for the DLL - It is empty!
There is only one namespace involved MyNamespace.Configuration - this is a new / nearly empty assembly with no dependencies other than System.Configuration in the GAC, the host project and referenced assembly are both using .Net Framework 4.0
The part of the application that is trying to load the affected assembly is:
<configProtectedData defaultProvider="DynamicFileConfigurationProvider">
<providers>
<add name="DynamicFileConfigurationProvider"
type="MyNamespace.Configuration.DynamicFileConfigurationProvider,
MyNamespace.Configuration, Version=1.0.0.0, Culture=neutral, PublicKeyToken=aeecd94c462a579a"
SelectorKeyProviderName="HostNameSelectorKeyProvider"/>
</providers>
</configProtectedData>
Update:
Setting shadowCopyBinAssemblies to false had the effect of causing the binder to look at ../Microsoft.NET/Framework/v4.0.30319/Temporary ASP.NET Files/... Rather than the previous IIS Express location
Intercepting the exception earlier did not provide any additional information, simply the same message that the file could not be found.
Referencing the assembly in another host, both console and web turned up no info, the assembly loads fine and the methods can be called.
Manually placing the assembly in the location in which the binder is looking for it also works - It seems to me that the assembly binder is looking in the wrong place. i.e. if shadowCopyBinAssemblies is false, then it should only look in the bin folder. if shadowCopyBinAssemblies is true then the shadow copy location should have my app's dll's as well as any that it references - it shouldn't be empty.
Basically, Temporary ASP.NET Files folder contains assembly copies to allow file updates in the bin folder. When the runtime loads an assembly, it becomes locked and thus you cannot update your assemblies on the server. To solve the problem, the runtime copies them into the "Temporary ASP.NET Files" folder.
I'd try to tackle the problem as following:
Try to disable show copying (<hostingEnvironment shadowCopyBinAssemblies="false" /> or http://msdn.microsoft.com/en-us/library/system.appdomainsetup.shadowcopyfiles.aspx) to check if the problem really relates to Temporary ASP.NET Files.
Try to get more details about the exception using "Break on exception" feature in VS or by using an exception handler. Check exception.Data and .FusionLog properties for more detailed information about the exception.
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler((x, y) =>
{
var exception = y.ExceptionObject as System.IO.FileNotFoundException;
if (exception != null)
// Retrieve exception information here
});
Try to load the problematic assembly in a separate project. Even a simple console app will be fine.
These activities will allow you to narrow cause of the problem.
Not sure about the cause in MVC application, but I encountered a similar kind of issue in my web form based web application where Referenced Assembly where we set to CopyLocal = True. My web project was referencing assemblies both from the GAC and a folder located in the relative path inside the solution.
I resolved the issue by
Removing all the assemblies that were referenced form the relative path
Manually deleted the debug and release folders in both bin and obj folders for all projects.
Added back the assemblies from the local path.
Re-build the project
And things started working. You should probably try these steps as well and this might help resolve the issue.
C#, VS2010, .Net 4.0, ASP.NET service under IIS or IIS Express.
I'm using a 3rd party assembly within my service. This 3rd party assembly has a .config file and is loaded dynamically as such:
Service -> MyAssembly1 -> Dynamically Load MyAssembly2 using Assembly.Load() -> 3rd Party Assembly with .config
I'm normally a C++ developer so this ASP.NET stuff is rather new to me.
I understand that with an ASP.NET application the assemblies it uses are "shadow-copied" to the Temporary ASP.NET Files folder.
Unfortunately when this 3rd party assembly is "shadow-copied" its .config file is not. So when it comes time to use this assembly it's failing because it cannot open its .config file.
From within my assembly I'm able to get the CodeBase for that assembly and load the .config file myself, but that doesn't help me since this 3rd party assembly needs to open the file itself.
If I manually copy the .config file to the shadow-copy location it works great.
Also, this 3rd party called the config file "assemblyname.config" instead of "assemblyname.dll.config".
The error I get is:
Unable to load configuration file: "\assemblyname.config".
When this 3rd party assembly is used in a non ASP.NET app (ie a normal Windows app) it works great since it doesn't do the shadow-copy stuff. Just uses the assembly and .config file directly from the exe location.
Any ideas? I've been unable to find a solution though I'd think this would be a rather common issue.
The main thing when loading assemblies is to see the path where the assembly is placed on disk and the page directory from which you are trying to load the assembly. So if you are adding the path for loading the assembly that does not mean that from the same path it will load the config file. Please try to put them both in the root folder of the app and see if the issue remains.
So I'm trying to use a .Net Assembly in my web services project. This assembly requires lots of settings in App.config. But my web service doesn't have an App.config, it has a web.config. It seems that it uses sections that an app.config would have that don't even exist for web projects. Is there any way I can make this assembly work? (make it read another config file maybe?)
You should be able to simply use the same configuration sections in the web.config file that exist in the app.config and it would work.
The way the configuration subsystem works means that it does not matter.
Typically we keep our config values in web.config/app.config and for the environment global config varialbes (and not application specific) in server machine.config file.
When deploying an object to the GAC where is the best location to keep these config type values? It seems that the best location would be a linked resource file.
Does anyone have any experience/recommendation with this approach? (sample code?)
thx
The configuration values need to be in the application configuration of the executing assembly. It is the responsibility of the application to have the configuration values so that your assembly will have access to them when it is loaded into the AppDomain.
I've had a need for assembly-specific config files (as opposed to executing assembly config files) in the past.
For an assembly in the GAC, it is possible (but not recommended) to physically copy a config file to the assembly dll folder.
The solution I've used for creating a config file that can be shared across assemblies regardless of AppDomain is a a simple registry entry for my application that defines a shared config file location. This way, any assembly can retrieve configuration settings from a shared location, regardless of which executing assembly launched it. (especially useful for scripting - otherwise, you'd have to deploy a config file named wscript.exe.config in the windows\system32 folder - UGH!)
if you dont care of having specific configuration for each application using your dll you can place the configuration in the machine.config file inside the framework folder.
%systemRoot%/Windows/Microsoft.Net/Framework/[Version]/Machine.config