getasync - postasync httpclient c#
La solicitud HttpClient arroja IOException (3)
El siguiente código arroja una IOException con el mensaje: "La clave de registro especificada no existe".
HttpClient client = new HttpClient();
Uri uri = new Uri("http://www.google.com");
client.GetAsync(uri);
Esto es solo en una aplicación de consola en Main. Parece que el error está siendo lanzado por mscorlib.dll! Microsoft.Win32.RegistryKey.Win32Error (int errorCode, string str). No tengo idea de por qué se está lanzando este error o cómo comenzar a depurarlo.
Editar rastro de pila:
en Microsoft.Win32.RegistryKey.Win32Error (Int32 errorCode, String str)
Es solo 1 línea y no hay excepción interna, etc.
La pila de llamadas es:
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]
Estoy de acuerdo con la respuesta de Ligaz, y he registrado un problema de conexión sobre este error: https://connect.microsoft.com/VisualStudio/feedback/details/773666/webrequest-create-eats-an-ioexception-on-the-first-call#details
Guarde lo siguiente en un archivo .reg e impórtelo al registro para evitar que se produzca este error:
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
Parece que esto se debe a una actualización de seguridad reciente para .NET Framework: MS12-074: las vulnerabilidades en .NET Framework podrían permitir la ejecución remota de código: 13 de noviembre de 2012 (KB 2745030)
Todo se reduce al siguiente código en la resolución de proxy web:
[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)
{
}
}
Como puede ver, busca una clave de registro específica mencionada en el artículo de KB. También debe tener en cuenta que la excepción está interceptada internamente, pero la ve porque ha habilitado Excepciones de primera oportunidad en las opciones de depuración de Visual Studio.
Si no desea ver esta excepción, debe agregar la clave de registro especificada con el valor 0
:
Registry location: HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/.NETFramework
DWORD (32-bit) Value name: LegacyWPADSupport
Value data: 0
y para procesos de 32 bits en máquinas de 64 bits:
Registry location: HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/Microsoft/.NETFramework
DWORD (32-bit) Value name: LegacyWPADSupport
Value data: 0
Por alguna razón, su código HttpClient
está buscando configuraciones de proxy en el registro y no puede abrir la clave. Una mirada a través del código muestra que intenta abrir HKCU y luego ir a una de las siguientes teclas en orden:
-
"HKCU//SOFTWARE//Microsoft//Windows//CurrentVersion//Internet Settings//Connections"
-
"HKLM//SOFTWARE//Microsoft//Windows//CurrentVersion//Internet Settings//Connections"
-
"HKLM//SOFTWARE//Policies//Microsoft//Windows//CurrentVersion//Internet Settings"
Uno de estos tres es potencialmente la clave a la que su proceso no tiene acceso, por lo que no estoy seguro. Una posible solución es desactivar la detección automática de la configuración del proxy.
De lo contrario, deberá averiguar exactamente qué clave está cargando y lo haremos con dos pasos.
- Habilite el registro de System.Net .
- Descargue y ejecute Procmon, filtrando en el acceso de registro para su aplicación, así:
- Una vez abierto, deshabilite la captura si está habilitado (la lupa debe tener una X roja a través de él).
- Comience a filtrar en el nombre de su proceso.
- Deseleccione todas las opciones excepto las entradas de registro
- Habilite la captura (haga clic en la lupa)
- Ejecute su aplicación
- Encuentre la entrada ofensiva en el registro, haga doble clic para ver qué tecla estaba abriendo
Una vez que determine la clave ofensiva, puede trabajar para descubrir por qué su aplicación no tiene acceso a ella. Quizás, si el nombre de su aplicación es una indicación, la cuenta de usuario en la que se está ejecutando su servicio carece de acceso a la clave de registro.