I have a strange issue, which drives me crazy…
I have a simple Class Library Project (Full .NET Framework, 4.6.1) with a wrapper class for functionality around Cosmos DB. Therefore I have added the “Microsoft.Azure.DocumentDB” NuGet Package 1.19.1 to this project. Other than that, I have a reference to the “Newtonsoft.Json” NuGet Package 10.0.3, as well as to a couple of "Microsoft.Diagnostics.EventFlow.*" NuGet Packages.
So far, everything compiles without any error.
But as soon as I hit my wrapper class – consumed from a simple Service Fabric Stateless Service (Full .NET Framework 4.6.1) – and try to execute the following line of code:
_docClient = new DocumentClient(new Uri(cosmosDbEndpointUrl), cosmosDbAuthKey);
I get this strange error at runtime:
System.IO.FileNotFoundException occurred HResult=0x80070002
Message=Could not load file or assembly 'System.Net.Http,
Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or
one of its dependencies. The system cannot find the file specified.
Source= StackTrace: at
Microsoft.Azure.Documents.Client.DocumentClient.Initialize(Uri
serviceEndpoint, ConnectionPolicy connectionPolicy, Nullable1
desiredConsistencyLevel) at
Microsoft.Azure.Documents.Client.DocumentClient..ctor(Uri
serviceEndpoint, String authKeyOrResourceToken, ConnectionPolicy
connectionPolicy, Nullable
1 desiredConsistencyLevel)
Inner Exception 1: FileNotFoundException: Could not load file or
assembly 'System.Net.Http, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The
system cannot find the file specified.
I have absolutely no clue, why the System.Net.Http assembly is not found at all – there is even a assembly reference in my class library project to the .Net Framework Assembly “System.Net.Http 4.0.0.0”.
What I also do not understand is, that there is this weird binding redirect to 4.2.0.0 – where is that one coming from?
To get around this one, I tried to add the following redirect to the app.config of the Service Fabric Service (which is consuming the class library):
But still no difference, I still get the error at runtime.
Anybody having a clue? Anybody having seen such issue?
Thanks and regards,
OliverB
The problem you're facing is related to Visual Studio, especially 2017 which is shipped with System.Net.Http v4.2.0.0
. However, adopting the new way whereby any references should be done via NuGet, latest version of System.Net.Http
which is 4.3.3 contains the dll version 4.1.1.2.
The problem is that VS at build time and at run time as well will ignore your reference and it will try to reference the DLL it knows about.
How to fix it:
If you look online on google you'll find a few open issues with Microsoft about this, so hopefully they'll fix this in the future.
Hope this helps.
Update:
When looking at finding some permanent fixes for this issue to work on the build agents, noticed that if you migrate to the new NuGet PackageReference model (in .csproj
not in packages.config
) tends to work better. Here's a link to the guide on how to do this upgrade: https://docs.microsoft.com/en-us/nuget/reference/migrate-packages-config-to-package-reference
Removing binding redirect worked for me, you can try removing it:
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
An addition to the answer @AndreiU already gave and how to reproduce runtime errors locally.
I got the runtime error below when deploying to Azure, not locally.
{"Message":"An error has occurred.","ExceptionMessage":"An error
occurred when trying to create a controller of type 'OrderController'.
Make sure that the controller has a parameterless public
constructor.","ExceptionType":"System.InvalidOperationException","StackTrace":"
at
System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage
request, HttpControllerDescriptor controllerDescriptor, Type
controllerType)\r\n at
System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage
request)\r\n at
System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()","InnerException":{"Message":"An
error has occurred.","ExceptionMessage":"Could not load file or
assembly 'System.Net.Http, Version=4.2.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The
system cannot find the file
specified.","ExceptionType":"System.IO.FileNotFoundException","StackTrace":"
at Company.Project.Service.CompanyIntegrationApiService..ctor(Uri
baseAddress)\r\n at
Company.Project.BackOffice.Web.Controllers.OrderController..ctor() in
C:\projects\company-project\src\Company.Project.BackOffice.Web\Controllers\Order\OrderController.cs:line
30\r\n at lambda_method(Closure )\r\n at
System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage
request, HttpControllerDescriptor controllerDescriptor, Type
controllerType)"}}
When I started looking at assemblies I could see that my web project and service project targeted different versions for System.Net.Http
.
Web project:
Service project:
It's easy to think that this is caused by a mismatch in versions but the key here is to look at the error The system cannot find the file specified.
.
Looking at the path property we can see that the web project targets a .Net Framework assembly while the service targets an assembly from Visual Studio 2017. Since the server does not have Visual Studio 2017 installed, the runtime error will occur.
Web path:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Net.Http.dll
Service path:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll
Something as simple as setting Copy Local
to true
can fix the problem, however not in all cases.
In order to reproduce the error on your local machine, simply remove the needed System.Net.Http.dll
from the Visual Studio specific folder. This will will give you the runtime error and probably some build errors. After these are fixed everything should work, at least it did for me.
If you have installed System.Net.Http
via NuGet
check which assembly is used by looking at the .csproj
version. System.Net.Http 4.3.4
gives the following assembly for example:
<Reference Include="System.Net.Http, Version=4.1.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
If you use a build server like Jenkins, TeamCity or AppVeyor the runtime missing .dll
might exist there as well. In this case it might not help to use NuGet version of System.Net.Http or deleting the missing .dll
locally. To solve this error look at the version that is not found and the specific PublicKeyToken
. After that create a binding redirect in either Web.config
or App.config
depending on your project. In my case I would like to use 4.0.0.0 instead:
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
A good Github thread about the issue:
https://github.com/dotnet/corefx/issues/22781
I had the same problem. In the end I solved it by changing the Deploy-FabricApplication.ps1 to something like this
$binFolder = "$LocalFolder\..\..\..\..\Bin"
$httpDllLocation = "$binFolder\System.Net.Http.dll"
$codeFolder = "$ApplicationPackagePath\[ProjectName].ServicesPkg\Code"
$configFile = "$codeFolder\[ProjectName].Services.exe.config"
Copy-Item $httpDllLocation -Destination $codeFolder
$appConfig = [xml](cat $configFile)
$appConfig.configuration.runtime.assemblyBinding.dependentAssembly | foreach {
$name = $_.assemblyIdentity.name
#Write $name
if($name -eq 'System.Net.Http')
{
Write 'System.Net.Http changed'
$_.bindingRedirect.newVersion = '4.2.0.0'
}
}
$appConfig.Save($configFile)
I found an 4.2.0.0 System.Net.Http.dll that is x64. Before deploying this script copies the dll to the package directory and changes the config file to explicitly use this file. I also wrote a blog about my System.Net.Http problems at http://gertjanvanmontfoort.blogspot.nl/2017/11/systemnethttp-dll-version-problems.html
Do not forget to replace the [ProjectName] with your own project name
Hope this helps, feel free to ask
I encountered this error when I deployed a web service to one of our servers. The project targeted .Net framework 4.7.2, which wasn't installed on the server. Installing the 4.7.2 framework on the server corrected the problem.
I was using System.Net.Http
to make a post request to validate the google captcha token using Owin and I was receiving this error. The only solution that worked perfectly was removing HttpClient
requisition and add RestSharp
instead.