I have three projects in my solution:
A WCF web service which provides functionality I want to test
A Web Application which calls that web service
A test project which runs tests on the service.
The web service and the web application both use log4net with separate configuration files and this line in the AssemblyInfo.cs for configuration:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
When I browse to the URL of the web service (http://localhost/MyWebService/MyWebService.svc), It appears as expected - information and a link to the wsdl.
When I use the web application, it all works correctly. The code calls the web service and gets correct responses in reply. Logging occurs from both the web app and the web service.
However, when I run my unit tests, they all fail with the following exception:
Test method MyServiceTest.MyServiceAuthTest.TestValidateCorrectly threw exception: System.ServiceModel.ServiceActivationException: The requested service, 'http://localhost/MyWebService/MyWebService.svc' could not be activated. See the server's diagnostic trace logs for more information.
In the Event logs for my local machine, I get the following message:
WebHost failed to process a request.
Sender Information: System.ServiceModel.ServiceHostingEnvironment+HostingManager/12905972
Exception: System.ServiceModel.ServiceActivationException: The service '/MyWebService/MyWebService.svc' cannot be activated due to an exception during compilation. The exception message is: Could not load file or assembly 'log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821' or one of its dependencies. Strong name signature could not be verified. The assembly may have been tampered with, or it was delay signed but not fully signed with the correct private key. (Exception from HRESULT: 0x80131045).
I've removed and replaced the references, cleaned and rebuilt, and even purged the temporary asp.net files, all to no avail. The web site calls the service with no problems, but the tests fail.
Does anyone know what could be happening here?
Update: I removed all references to log4net and the tests ran and succeeded without a problem. Obviously, this is far from preferable. Any suggestions?
Update 2: Some combination of these two things fixed the problem:
Added a reference to log4net in my test project, making sure to initialise it completely.
Used the release build of log4net 1.2.10 rather than the debug build.
Do you have a reference from your unit test to the log4net library? Try it out.
The reason behind this: Most unit testing frameworks are shadowing the binaries to somewhere else during the test run, but by doing this they do not find deeply nested references in all cases. I once met this with NHibernate and log4net. In case of MSTest you cannot deactivate shadowing. NUnit GUI has an option for this, but I don't have it installed, so you have to look for it on your own :-)
I would also consider to add log4net handling into your unit tests configuration. This is very helpful when looking at failures anyway.
This link explains it for NUNit and it should be possible for other frameworks as well.
Related
We have a .NET solution that I'm trying to get to run in our new CI environment, TeamCity.
The solution builds and runs, and all unit tests run (not all pass, but that's a different story) on our dev machines.
It builds properly on the CI server as well, but when running the MSTest configuration, it fails, giving a message like:
Unable to load the test container '[one of my test assemblies]' or one of its dependencies. Error details: System.IO.FileNotFoundException: Could not load file or assembly '[one of my assemblies]' or one of its dependencies. The system cannot find the file specified.
Well, my assembly is built and available, so that's unlikely. On my local dev machine, I can get more detail with procmon or the like to see where the dependency chain is broken, but I'm not sure how I can do that against a remote server.
How can I find out what my CI server is missing to do its job? Is there some logging I can enable or something?
Sounds like the working directory is wrong when you are attempting to run tests.
Is your Build and Unit Tests steps in the same "Build Configuration"?
I am getting an annoying build warning in my web config. I have about 40 warnings of Global element '{element name}' has already been declared for all the elements in my web config. This is for a WCF service I am creating in the same solution as an MVC website. I suspect that the issue is that the WCF service references the MVC assembly (to reflect some metadata), and both web config files are somehow being included resulting in duplicate items. Searching has only turned up different issues than the one I am having.
Is there any way to fix this issue, perhaps by telling the configuration manager to ignore the config file in the referenced MVC assembly?
EDIT: While trying to separate my different dependencies as much as possible, my warning messages went away after shutting down the computer.
Separate your service from your host. IE have your service in a more or less pure assembly and then reference that from your console host, your wcf host, your windows service host and your mvc host projects separately.
I have a web service that once deployed mysteriously needs other DLLs to work.
I have a website running in C:\inetpub\wwwroot\MyWebsite and the web service running in C:\inetpub\wwwroot\MyWebsite\WebService
I created an application (WebService, pointing to C:\inetpub\wwwroot\MyWebsite\WebService) in IIS under the website MyWebsite
When running one of WebService's .svc, I get:
Could not load file or assembly 'Blah.Web' or one of its dependencies. The system cannot find the file specified.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.IO.FileNotFoundException: Could not load file or assembly 'Blah.Web' or one of its dependencies. The system cannot find the file specified.
Blah.web is a DLL used for MyWebsite. Why do suddenly my WebService needs this DLL that's not even referenced in VS 2010 ?
Is it a web.config thing ?
Thanks,
It's because your web service is nested within your website, so when your website automatically compiles, it's compiling the code in your main website AND the web service website. However, since the compiler is functioning undert he context of the main website, it's looking in mywebsite\bin for the code instead of \mywebsite\myservice\bin.
Personally, I'd change the architecture and have the web services site separate, and not nested. it should be, at a minimum, its own web Applicaiton (as configured in IIS) or a separate web site.
I have been implementing RSA security for a project I am working on.
I'm using the SecurID4Net files found on the web to get this rolling, which by default are targeted to the .Net 2.0 framework, ANY CPU.
I created a derived SqlMembershipProvider which references the SecurID4Net.Interfaces project, targeting .Net 4.0, any CPU.
My class lib "Services" references the SqlMembershipProvider, also targeting Any CPU.
My web app "Services.Web" references the "Services" lib, .Net 4.0, Any CPU.
I'm not using the client profile for any assembly targeting .Net 4. Every reference I have described here has Copy Local set to True.
I have my local IIS default web site set up to my output folder for the web project, so I can Ctrl-Shift-B and browse my IIS folder. When my client app signs in for the first time (possibly 2 or 3 times), it works fine, but after that sign ins fail. Additionally, when attaching to the IIS7 process (Services.Web), I would get the following error:
System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.Assembly.GetTypes()
at Microsoft.Tools.SvcHost.ServiceHostHelper.LoadServiceAssembly(String svcAssemblyPath)
The DLL it is having problems loading is the SqlMembershipProvider I created.
So, I changed the SecurID4Net.Interfaces project to target .Net 4.0, and recompiled. It seems to work consistently now (still testing this part), but CTRL-ALT-P to attach to the IIS process still results in the WcfSvcHost error popping up before I can actually attach to the process... everything else seems to be working.
I'm running my VS as admin so I can attach to an IIS process;
All references described are set to Copy Local = true;
All assemblies are targeting .Net 4.0 Full Profile;
All assemblies are reachable, not blocked by the copy operation to the server where this is hosted;
To my knowledge no syntax issues with the web.config.
Anyone have any ideas why this error keeps popping up? Why would this error pop up when everything seems to be working?
I think I found the answer almost immediately. After inspecting each AssemblyInfo.cs file in the chain of projects, I found this in my SqlMembershipProvider assembly:
[assembly: AssemblyCulture("EN-us")]
I removed the value so it's an empty string.
I had a very similar issue in another project I worked on a few months ago where the web site had this filled in, and the web site worked on the very first load, but every load thereafter failed with a very cryptic error which, after drilling down, found that it could not load the assembly, giving a FileNotFoundException.
I don't know why this tiny, simple attribute would cause so many headaches...
EDIT: I'm 99% certain this was it. When I attach to my IIS process I no longer get a WcfSvcHost error.
I have a C# WinForms Project which contains some WCF service definition files which I have created in the project by adding standard classes (not using Add Item > WCF Service).
The project contains some dependencies that require me to build the project for x86 processors.
If I edit the app.config file with the WCF Service Configuration Editor and try to use the "Create New Service ..." wizard, and then browse to the project EXE file (in the debug folder) I get an error, (which I've read is because I'm targeting the x86 processor):
Could not load file or assembly 'EXE_FILE_NAME' or one of its dependencies. An attempt was made to load a program with an incorrect format.
So, upon changing the target to All CPUs, compiling the project again, and then trying to create the service in the WCF Service Configuration Editor again, I now get a different error:
Could not load file or assembly 'SOLUTION_NAME, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
(To clarify, I CAN still compile the project when targeting all CPUs, but get an error at runtime due to a dependency)
Is anybody able to help me with this problem, so I can add the services defined in app.config file using the wizards in WCF Service Configuration Editor? (I think that if I add the services to the WCF Service Configuration Editor when targeting All CPUs I can make any modifications thereafter, regardless of the target)
When debugging, look at the exception detail. From what you've described my guess is you will an assembly loading error in the fusion log because the dependencies of the WCF service can't be satisfied by looking in the default locations.
Say for example you're referencing MrCritter.MyService.dll which defines a WCF service and has a dependency on something like log4net or nHibernate. As long as nothing from those dependencies is leaking into the WCF host (eg returning an ILog) yes you'll be able to compile fine but will get ReflectionTypeLoadException thrown when trying to instantiate the service class if those dependencies aren't somewhere it can find (eg in the executing directory, in GAC etc).