Nie znaleziono dziwnego problemu z System.Net.Http 4.2.0.0

108

Mam dziwny problem, który doprowadza mnie do szału…

Mam prosty projekt biblioteki klas (pełna .NET Framework, 4.6.1) z klasą opakowującą dla funkcjonalności wokół Cosmos DB. Dlatego dodałem pakiet NuGet 1.19.1 „Microsoft.Azure.DocumentDB” do tego projektu. Poza tym mam odniesienie do pakietu NuGet „Newtonsoft.Json” 10.0.3, a także do kilku pakietów NuGet „Microsoft.Diagnostics.EventFlow. *”.

Jak dotąd wszystko kompiluje się bez żadnego błędu.

Ale gdy tylko trafię na moją klasę otoki - zużywaną z prostej usługi bezstanowej usługi Service Fabric (pełna .NET Framework 4.6.1) - i spróbuj wykonać następujący wiersz kodu:

_docClient = new DocumentClient(new Uri(cosmosDbEndpointUrl), cosmosDbAuthKey);

Otrzymuję ten dziwny błąd w czasie wykonywania:

Wystąpił wyjątek System.IO.FileNotFoundException HResult = 0x80070002
Message = Nie można załadować pliku lub zestawu „System.Net.Http, Version = 4.2.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a” lub jednej z jego zależności. System nie może odnaleźć określonego pliku.
Source = StackTrace: at Microsoft.Azure.Documents.Client.DocumentClient.Initialize (Uri serviceEndpoint, ConnectionPolicy connectionPolicy, Nullable 1 desiredConsistencyLevel) at Microsoft.Azure.Documents.Client.DocumentClient..ctor(Uri serviceEndpoint, String authKeyOrResourceToken, ConnectionPolicy connectionPolicy, Nullable1 pożądaneConsistencyLevel)

Wyjątek wewnętrzny 1: FileNotFoundException: nie można załadować pliku lub zestawu „System.Net.Http, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a” lub jednej z jego zależności. System nie może odnaleźć określonego pliku.

Nie mam absolutnie pojęcia, dlaczego w ogóle nie znaleziono zestawu System.Net.Http - w moim projekcie biblioteki klas znajduje się nawet odniesienie do zestawu .Net Framework Assembly „System.Net.Http 4.0.0.0”.

Czego też nie rozumiem, to to, że jest to dziwne przekierowanie do 4.2.0.0 - skąd to pochodzi? Aby obejść ten problem, próbowałem dodać następujące przekierowanie do pliku app.config usługi Service Fabric (która zużywa bibliotekę klas):

Ale nadal bez różnicy, nadal pojawia się błąd w czasie wykonywania.

Czy ktoś ma wskazówkę? Czy ktoś widział taki problem?

Dzięki i pozdrawiam, OliverB

OliverB
źródło
3
Cześć, OliverB! Czy znalazłeś obejście tego problemu? Po prostu mam taką samą sytuację i to jest koszmar :-(
user1178399
@HansPassant, że link jest teraz uszkodzony
reggaeguitar
odpowiadam na to: stackoverflow.com/a/63031440/330680
Mahdi

Odpowiedzi:

129

Problem, z którym się spotykasz, jest związany z programem Visual Studio, zwłaszcza 2017, który jest dostarczany z System.Net.Http v4.2.0.0. Jednak przyjęcie nowego sposobu, w którym wszelkie odwołania powinny być wykonywane za pośrednictwem NuGet, którego najnowsza wersja System.Net.Httpto 4.3.3 zawiera dll w wersji 4.1.1.2.

Problem polega na tym, że program VS w czasie kompilacji, a także w czasie wykonywania, zignoruje twoje odwołanie i spróbuje odwołać się do biblioteki DLL, o której wie.

Jak to naprawić:

  • upewnij się, że wszelkie odwołania do System.Net.Http są wykonywane za pośrednictwem NuGet
  • Błędy czasu kompilacji: zmień rozszerzenie System.Net.Http.dll (lub przenieś je w inne miejsce ... w zasadzie pozbądź się go), które jest dostarczane z VS 2017 ( c:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\); jeśli masz inną wersję, ścieżka będzie się nieco różnić, choć niewiele
  • Błędy czasu wykonywania: dodaj przekierowanie powiązania zestawu

Jeśli zajrzysz do Google w Internecie, znajdziesz kilka otwartych problemów z Microsoftem na ten temat, więc miejmy nadzieję, że naprawią to w przyszłości.

Mam nadzieję że to pomoże.

Aktualizacja:

Patrząc na znalezienie pewnych trwałych poprawek dla tego problemu, aby działały na agentach kompilacji, zauważyłem, że po migracji do nowego modelu NuGet PackageReference ( .csprojnie w packages.config) zwykle działa lepiej. Oto link do przewodnika, jak wykonać tę aktualizację: https://docs.microsoft.com/en-us/nuget/reference/migrate-packages-config-to-package-reference

Andrei U
źródło
Wygląda na to, że wbijają wersję
Paul Miller
6
Wielkie dzięki, od kilku godzin szaleję, próbując rozwiązać ten problem!
Flinkman
22
Tylko ostrzeżenie, że problem można rozwiązać, faktycznie usuwając bindingRedirects, jeśli pracujesz z .NET 4.7.2.
Alternatex
1
Ten sam problem podczas aktualizacji do wersji 4.7.2. Dotyczyło to również System.IO.Compression i System.Runtime. Usunięcie przekierowań powiązań rozwiązało problem.
JB. Z Monicą.
7
Tak! Wreszcie! Zgodnie z @Alternatex i JB powyżej, dla 4.7.2 usuń bindingRedirects i teraz złote. Co za ból przy każdej aktualizacji frameworka, która zawiera najnowsze rutyny związane z piosenkami i tańcami potrzebne dla System.Net.Http.
Ted
76

Usunięcie przekierowania wiązania zadziałało dla mnie, możesz spróbować je usunąć:

<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
Vivek Sharma
źródło
2
To była jedna z pierwszych rzeczy, których próbowałem, ale bez powodzenia
OliverB
2
Usunięcie wiązaniaRedirect rozwiązało problem za mnie. Testy jednostkowe nie przechodziły z tym samym błędem co OP i teraz działają.
Edu,
1
Czy to jest pełna linia kodów? A gdzie dokładnie należy to dodać? Wszystkie moje inne bindRedirect znajdują się pod tagiemdependentAssembly
Flo
1
To działało świetnie. Dodam, że jeśli masz wiele projektów w swoim rozwiązaniu, upewnij się, że oceniasz je wszystkie i rozwiążesz za pomocą tej metody.
Skuter
1
Dziękuję Ci. Utknąłem w tej sprawie od 2 dni. Zadziałało !!!
Sagar Khatri
17

Dodatek do odpowiedzi już podanej przez @AndreiU i jak lokalnie odtwarzać błędy uruchomieniowe.

Podczas wdrażania na platformie Azure, a nie lokalnie, wystąpił poniżej błąd środowiska wykonawczego.

Nie można załadować pliku lub zestawu „System.Net.Http, Version = 4.2.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a” lub jednej z jego zależności. System nie może znaleźć określonego pliku. "," ExceptionType ":" System.IO.FileNotFoundException "," StackTrace ":" w Company.Project.Service.CompanyIntegrationApiService..ctor (Uri baseAddress) \ r \ n at Company.Project .BackOffice.Web.Controllers.OrderController..ctor () w 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 (żądanie HttpRequestMessage, HttpControllerDescriptor controllerDescriptor, Type controllerType) "}} Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a 'lub jedna z jego zależności. System nie może znaleźć określonego pliku. "," ExceptionType ":" System.IO.FileNotFoundException "," StackTrace ":" w Company.Project.Service.CompanyIntegrationApiService..ctor (Uri baseAddress) \ r \ n at Company.Project .BackOffice.Web.Controllers.OrderController..ctor () w 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 (żądanie HttpRequestMessage, HttpControllerDescriptor controllerDescriptor, Type controllerType) "}} Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a 'lub jedna z jego zależności. System nie może znaleźć określonego pliku. "," ExceptionType ":" System.IO.FileNotFoundException "," StackTrace ":" w Company.Project.Service.CompanyIntegrationApiService..ctor (Uri baseAddress) \ r \ n at Company.Project .BackOffice.Web.Controllers.OrderController..ctor () w 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 (żądanie HttpRequestMessage, HttpControllerDescriptor controllerDescriptor, Type controllerType) "}}

Kiedy zacząłem przeglądać zestawy, zauważyłem, że mój projekt sieci Web i projekt usługi były przeznaczone dla różnych wersji System.Net.Http .

Projekt internetowy:

wprowadź opis obrazu tutaj

Projekt serwisowy:

wprowadź opis obrazu tutaj

Łatwo jest pomyśleć, że jest to spowodowane niedopasowaniem wersji, ale kluczowe jest tutaj przyjrzenie się błędowi The system cannot find the file specified. .

Patrząc na właściwość path, widzimy, że projekt sieci Web jest przeznaczony dla zestawu .Net Framework, podczas gdy usługa jest przeznaczona dla zestawu z programu Visual Studio 2017. Ponieważ na serwerze nie jest zainstalowany program Visual Studio 2017, wystąpi błąd w czasie wykonywania.

Ścieżka internetowa:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Net.Http.dll

Ścieżka serwisowa:

C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll

Coś tak prostego jak ustawienie Copy Local, aby truemożna rozwiązać ten problem, jednak nie we wszystkich przypadkach.

wprowadź opis obrazu tutaj

Aby odtworzyć błąd na komputerze lokalnym, po prostu usuń potrzebne pliki System.Net.Http.dll z folderu określonego programu Visual Studio. Spowoduje to błąd w czasie wykonywania i prawdopodobnie błędy kompilacji. Po ich naprawieniu wszystko powinno działać, przynajmniej mi się udało.

Jeśli zainstalowałeś System.Net.Httpza pomocą, NuGetsprawdź, który zestaw jest używany, patrząc na .csprojwersję. System.Net.Http 4.3.4podaje na przykład następujący montaż:

<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>

Jeśli używasz serwera kompilacji, takiego jak Jenkins, TeamCity lub AppVeyor, .dllmoże tam również brakować środowiska wykonawczego . W takim przypadku może nie pomóc użycie wersji NuGet System.Net.Http lub usunięcie brakującego .dlllokalnego. Aby rozwiązać ten błąd, spójrz na wersję, która nie została znaleziona, i na konkretną wersję PublicKeyToken. Następnie utwórz przekierowanie wiążące w jednym Web.configlub w App.configzależności od projektu. W moim przypadku zamiast tego chciałbym użyć 4.0.0.0:

<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>

Dobry wątek na Githubie dotyczący problemu:

https://github.com/dotnet/corefx/issues/22781

Ogglas
źródło
4
dodanie <dependentAssembly> <assemblyIdentity name = "System.Net.Http" ....... działa dla mnie. dzięki
Romeo
Dla mnie też! Dziękuję za obejście! oldVersion = "0.0.0.0-4.2.0.0" newVersion = "4.1.1.3", ponieważ używam wersji 4.1.1.3
Pavel Yermalovich
Przekierowanie do 4.0.0.0 stawia mnie na szczycie. Dzięki!
Jim G.
Przekierowanie w dół jest niebezpieczne! Masz zależność w swoim projekcie, która sygnalizuje, że używa 4.2, ale wymuszasz używanie 4.0. Jeśli używa którejkolwiek z nowych właściwości lub metody wprowadzonej w wersji 4.0, wystąpi błąd w czasie wykonywania w trudnym do przewidzenia czasie.
David Burg
Link do wątku github jest martwy. Ale następujący wątek wydaje się zawierać odpowiednią dyskusję: github.com/dotnet/runtime/issues/24382
Hermann.Gruber,
5

Właśnie zainstalowałem System.Net.Httpza pomocą NuGet. Możesz go pobrać tutaj:

https://www.nuget.org/packages/System.Net.Http/

ASP.NET MVCProjekt pracuję nad celami .NET 4.6.1. Działa doskonale na moim komputerze podczas debugowania w IIS Expressprogramie Visual Studio 2019.

Problem wystąpił podczas próby uruchomienia aplikacji wdrożonej na platformie Azure. Otrzymałem ten błąd:

Nie można załadować pliku lub zestawu „System.Net.Http, Version = 4.2.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a” lub jednej z jego zależności.

To, co naprawdę zadziałało w moim przypadku, to otwarcie pliku .csproj i wyszukanie czegoś System.Net.Httptakiego jak na poniższym zrzucie ekranu ...

wprowadź opis obrazu tutaj

Zobacz, że .csprojplik ma wersję 4.1.1.3:

<Reference Include="System.Net.Http, Version=4.1.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">

W <HintPath>rzeczywistości wskazuje na..\packages folder z Nuget, to znaczy jest to prawdziwa wersja zainstalowana przez Nuget. Po wdrożeniu ta konkretna wersja zostanie również przywrócona po stronie serwera i wszystko powinno działać z przekierowaniem powiązania.

... więc przekierowanie powiązania powinno zawierać tę konkretną wersję w Web.confignastępujący sposób:

<dependentAssembly>
    <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.1.1.3" />
</dependentAssembly>

To rozwiązało problem w moim przypadku po kilku zatwierdzeniach do Azure Kudu . Witryna internetowa platformy Azure została ostatecznie uruchomiona bez błędów.

Leniel Maccaferri
źródło
4

To, co zrobiłem, aby naprawić problem, zostało usunięte ze wszystkich powiązań z pliku web.config i zrobiłem

Update-Package -reinstall

Spowodowało to usunięcie wielu starych wiązań, które prawdopodobnie nie muszą tam być, i faktycznie zrobiło dobre czyszczenie.

Jamie R Rytlewski
źródło
2

Napotkałem ten błąd podczas wdrażania usługi internetowej na jednym z naszych serwerów. Projekt dotyczył platformy .Net Framework 4.7.2, która nie była zainstalowana na serwerze. Zainstalowanie frameworka 4.7.2 na serwerze rozwiązało problem.

znak
źródło
To też był mój problem. Jest to powracający temat również dla innych wersji.
Jason Geiger
2

Odpowiedź Andrieja U prowadzi do mojego zbawienia. Jednak rozumowanie nie pasowało do mojego przypadku. Dla osób, które są w tym samym scenariuszu co ja:

Był to błąd czasu wykonania (nie czasu kompilacji), w którym kompilacja powiodła się, ale działała na jednym komputerze, ale nie na serwerze. Rozwiązanie: - Dodano pakiet System.Net.Http. - Zmień nazwę pliku: C: \ Program Files (x86) \ Reference Assemblies \ Microsoft \ Framework.NETFramework \ v4.7.2 \ System.Net.Http.dll (np. Zmień nazwę na: System.Net.Http.dll.BAK) na budować serwer.

Nie miałem i nadal nie mam przekierowań zestawu dla tej biblioteki dll

Sam
źródło
1

Jedno proste rozwiązanie, które znalazłem, obniża platformę docelową dla projektu internetowego do wersji 4.6.

Tworzę aplikację kliencką i internetową, klient ma .NET Framework 4.7.1, a sieć ma to samo i mam ten sam problem, kiedy obniżam wersję docelową .NET Framework dla sieci, to działa dla mnie.

Raquib
źródło
1

Po kilku dniach zmagania się z tym w końcu udało mi się rozwiązać problem .Net 4.7.2 / System.Net.Http dla mojego projektu. Oprócz zmiany pliku * .csproj na wersję docelową frameworka 4.7.2 musiałem również zaktualizować app.config w projektach z

<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />

do:

<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
Doug Boone
źródło
0

Miałem ten sam problem. W końcu rozwiązałem to, zmieniając plik Deploy-FabricApplication.ps1 na coś takiego

$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)

Znalazłem 4.2.0.0 System.Net.Http.dll, który jest x64. Przed wdrożeniem tego skryptu kopiuje bibliotekę dll do katalogu pakietu i zmienia plik konfiguracyjny, aby jawnie używać tego pliku. Napisałem także bloga o moich problemach z System.Net.Http pod adresem http://gertjanvanmontfoort.blogspot.nl/2017/11/systemnethttp-dll-version-problems.html

Nie zapomnij zamienić [ProjectName] na własną nazwę projektu

Mam nadzieję, że to pomoże, nie krępuj się zapytać

user8862383
źródło
0

Dla mnie było to coś naprawdę dziwnego. Potrzebne godziny debugowania po znalezieniu przyczyny. Nie wydarzyło się to lokalnie, ale tylko przy użyciu Jenkinsa do budowy projektu.

Miałem małą bibliotekę korzystającą z dotnet standart 2.0, a głównym projektem był projekt WCF oparty na normalnym .NET (mój był konkretnie w wersji 4.6.1). Ale w klasie startowej standardowej biblioteki dotnet miałem kod, który wyglądał następująco:

public static class CoreModule
{
    public static IServiceCollection AddStaticDataConfiguration(
        this IServiceCollection services, Func<IServiceProvider, IStaticDataConfiguration>  staticDataConfiguration) 
    {  
        services.TryAddSingleton(staticDataConfiguration);
        services.TryAddSingleton<Func<HttpClient>>(x =>
        {
            var configuration = staticDataConfiguration(x);

            return configuration.ClientResolver ?? (() => new HttpClient());
        });
        return services;
    }
}

Interfejs IStaticDataConfiguration wygląda jak poniżej:

public interface IStaticDataConfiguration
{
    //..... some stuff

    Func<HttpClient> ClientResolver { get; set; }
}  

Ten interfejs znajduje się w bibliotece standardowej dotnet, gdy implementacja znajduje się poza nią (znajduje się w projekcie WCF).

Spoza biblioteki wywoływałem AddStaticDataConfigurationmetodę jak poniżej:

serviceCollection.AddStaticDataConfiguration(p =>
{
    var staticDataConfig = p.GetService<IStaticDataConfiguration>();
    return new StaticDataProviderConfiguration
    {
        //...some other stuff
        ClientResolver = () => restRequestFactory.GetInstrumentedClient("StaticDataService") //this returns an HttpClient
    };
});

Problem polega na tym, że przechodzę Func<HttpClient>z normalnego projektu .NET do standardowej biblioteki dotnet, której z jakiegoś szalonego powodu standard dotnet nie lubi i może myśli, że HttpClientpochodzi z różnych klas, w wyniku czego rzuca System.Net.Http 4.x.x.xnot found wyjątek. Po usunięciu kodu, aby nie akceptować a HttpClientz normalnego projektu .NET, ale tworząc nową funcw samej bibliotece, jest szczęśliwy i działa dobrze. Mam nadzieję, że może to pomóc komuś innemu, ponieważ ten błąd występuje z wielu powodów :)

Rajmond Burgaj
źródło
0

Moje rozwiązanie było podobne do @ Raquib's. Mój projekt miał wersję 4.7.2 i działał dobrze na moim komputerze. Za każdym razem, gdy instalowałem na naszym serwerze deweloperskim, pojawiał się problem wspomniany w pytaniu. Okazuje się, że najwyższa wersja .net na serwerze to 4.6.1. Zmiana wersji mojego projektu na 4.6.1 rozwiązała problem. Aktualizacja wersji .net serwera nie była dla mnie opcją.

Bruno
źródło
0

Myślę, że część odpowiedzi można znaleźć w dokumentacji Microsoftu .

Podczas tworzenia aplikacji klasycznej w programie Visual Studio, która jest przeznaczona dla .NET Framework 4.5.1 lub nowszej wersji, aplikacja używa automatycznego przekierowywania powiązań.

Jak wskazuje odpowiedź @Vivek Sharma, usuwając:

<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />

rozwiązałem problem w 3 takich przypadkach w mojej aplikacji. Podczas badania biblioteki DLL za pomocą programu PowerShell, na przykład:

 ([system.reflection.assembly]::loadfile("C:\MyApp\bin\System.Net.Sockets.dll")).FullName

Wyjścia

System.Net.Sockets, wersja = 4.0.0.0

Najwyraźniej przekierowanie do powiązania 4.2.0.0nie zadziała, ponieważ wysyłamy dane 4.0.0.0do bin.

Warto też sprawdzić GAC, żeby zobaczyć czy tam też nie brakuje zespołu:

 gacutil -l System.Net.Sockets

W moim przypadku w GAC również brakowało konkretnej wersji. Jeśli biblioteka DLL znajdowała się w GAC, powinna zostać znaleziona w procesie wiązania zestawu .

P. Brian Mackey
źródło
-2

Najpierw usuń z lokalnego systemu plików:

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\Syste.Net.Http.dll

Następnie usuń wszystkie odwołania w projektach i dodaj odwołanie 4.0.
To rozwiązało mój problem.

Gogo Lazarovski
źródło
3
ojej nie, proszę nie uszkadzać swojej instalacji VS poprzez usuwanie niektórych jej plików.
David Burg