Запрос HttpClient вызывает исключение IOException


следующий код вызывает исключение IOException с сообщением: "указанный раздел реестра не существует."

HttpClient client = new HttpClient();

Uri uri = new Uri("http://www.google.com");

client.GetAsync(uri);

Это просто в консольном приложении в Main. Похоже, что ошибка выбрасывается mscorlib.dll!Microsoft.Win32.Объект registrykey.Win32Error (int errorCode, string str). Я понятия не имею, почему эта ошибка выбрасывается или как начать отладку этого.

изменить трассировку стека:

в Microsoft.Win32.Объект registrykey.Win32Error(код ошибки Int32, String str)

это всего лишь 1 строка, и нет внутреннего исключения exxception и т. д..

стек вызовов:

mscorlib.dll!Microsoft.Win32.RegistryKey.Win32Error(int errorCode, string str) + 0x189 bytes    
mscorlib.dll!Microsoft.Win32.RegistryKey.GetValueKind(string name) + 0x7f bytes 
System.dll!System.Net.HybridWebProxyFinder.InitializeFallbackSettings() + 0x9e bytes    
[Native to Managed Transition]  
[Managed to Native Transition]  
System.dll!System.Net.AutoWebProxyScriptEngine.AutoWebProxyScriptEngine(System.Net.WebProxy proxy, bool useRegistry) + 0xd0 bytes   
System.dll!System.Net.WebProxy.UnsafeUpdateFromRegistry() + 0x2c bytes  
System.dll!System.Net.Configuration.DefaultProxySectionInternal.DefaultProxySectionInternal(System.Net.Configuration.DefaultProxySection section) + 0x1d8 bytes 
System.dll!System.Net.Configuration.DefaultProxySectionInternal.GetSection() + 0xec bytes   
System.dll!System.Net.WebRequest.InternalDefaultWebProxy.get() + 0xcc bytes 
System.dll!System.Net.HttpWebRequest.HttpWebRequest(System.Uri uri, System.Net.ServicePoint servicePoint) + 0xdf bytes  
System.dll!System.Net.HttpWebRequest.HttpWebRequest(System.Uri uri, bool returnResponseOnFailureStatusCode, string connectionGroupName, System.Action<System.IO.Stream> resendRequestContent) + 0x2b bytes  
System.Net.Http.dll!System.Net.Http.HttpClientHandler.CreateAndPrepareWebRequest(System.Net.Http.HttpRequestMessage request) + 0x59 bytes   
System.Net.Http.dll!System.Net.Http.HttpClientHandler.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + 0xf4 bytes  
System.Net.Http.dll!System.Net.Http.HttpMessageInvoker.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + 0x4f bytes 
System.Net.Http.dll!System.Net.Http.HttpClient.SendAsync(System.Net.Http.HttpRequestMessage request, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) + 0x13e bytes 
System.Net.Http.dll!System.Net.Http.HttpClient.GetAsync(System.Uri requestUri, System.Net.Http.HttpCompletionOption completionOption) + 0xc bytes   

ConsoleServiceTest.exe!ConsoleServiceTest.Program.Main(string[] args) Line 20 + 0x17 bytes  C#
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x5a bytes  
    mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x285 bytes 
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x9 bytes   
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x57 bytes    
    mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x51 bytes   
    [Native to Managed Transition]  
3 70

3 ответа:

похоже, что это вызвано недавним обновлением системы безопасности для .NET Framework:MS12-074: уязвимости в .NET Framework могут позволить удаленное выполнение кода: 13 ноября 2012 г. (KB 2745030)

все это сводится к следующему коду в разрешение веб-прокси:

[RegistryPermission(SecurityAction.Assert, Read=@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework")]
private static void InitializeFallbackSettings()
{
    allowFallback = false;
    try
    {
        using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\.NETFramework"))
        {
            try
            {
                if (key.GetValueKind("LegacyWPADSupport") == RegistryValueKind.DWord)
                {
                    allowFallback = ((int) key.GetValue("LegacyWPADSupport")) == 1;
                }
            }
            catch (UnauthorizedAccessException)
            {
            }
            catch (IOException)
            {
            }
        }
    }
    catch (SecurityException)
    {
    }
    catch (ObjectDisposedException)
    {
    }
}

как вы можете видеть, он проверяет наличие определенного ключа реестра, описанное в статье базы знаний. Также вы должны отметить, что исключение поймано внутренне, но вы видите его, потому что вы включили первые случайные исключения в параметрах отладки Visual Studio.

если вы не хотите видеть это исключение, вы должны добавить указанный раздел реестра со значением 0:

Registry location: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework  
DWORD (32-bit) Value name: LegacyWPADSupport
Value data: 0

и для 32-битных процессов на 64-битных машинах:

Registry location: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework
DWORD (32-bit) Value name: LegacyWPADSupport
Value data: 0

Я согласен с ответом Лигаза, и я зарегистрировал проблему подключения об этой ошибке: https://connect.microsoft.com/VisualStudio/feedback/details/773666/webrequest-create-eats-an-ioexception-on-the-first-call#details

сохранить следующую .reg файл и импортировать его в реестр, чтобы предотвратить эту ошибку, чтобы быть поднятым:

Windows Registry Editor Version 5.00

; The following value prevents an IOException from being thrown and caught
; by System.Net.HybridWebProxyFinder.InitializeFallbackSettings() (in System.dll)
; when WebRequest.Create is first called.  By default the "LegacyWPADSupport"
; value doesn't exist, and when InitializeFallbackSettings calls GetValueKind,
; an IOException is thrown.  This adds the value with its default of false to
; prevent the exception.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
"LegacyWPADSupport"=dword:00000000

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]
"LegacyWPADSupport"=dword:00000000

по какой-то причине, ваш HttpClient код ищет настройки прокси в реестре и не может открыть ключ. Просмотр кода показывает, что он пытается открыть HKCU, а затем перейти к одному из следующих ключей по порядку:

  1. "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Connections"
  2. "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Connections"
  3. "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings"

один из этих трех потенциально является ключом, к которому ваш процесс не имеет доступа, почему я не уверен. Одним из возможных исправлений является отключение автоматического обнаружения Прокси Настройки.

в противном случае, вам нужно будет выяснить, какой именно ключ он загружает, и мы сделаем это с двумя шагами.

  1. включить System.Net ведение журнала.
  2. Загрузите и запустите Procmon, фильтруя доступ к реестру для вашего приложения, например:
  1. после открытия отключите захват, если он включен (увеличительное стекло должно иметь красный X через него).enter image description here
  2. начать фильтрацию на вашем имя процессов.enter image description here
  3. отменить выбор всех параметров, кроме записей реестра

enter image description here

  1. включить захват (нажмите на увеличительное стекло)
  2. запустите приложение
  3. найдите оскорбительную запись в журнале, дважды щелкните, чтобы увидеть, какой ключ он открывал

после того, как вы определите обидеть ключ, вы можете работать, чтобы выяснить, почему ваше приложение не имеет доступа к нему. Возможно, если имя вашего приложения является каким-либо указанием, учетная запись пользователя, под которой работает ваша служба, не имеет доступа к разделу реестра.