es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Descargando archivo sin enlace directo a través de C# Webclient

Estoy intentando descargar un archivo, pero el problema es que la URL no es un enlace directo al archivo zip, y mi código me muestra un error inútil.

Este es el código:

var zipFile = new FileInfo(Path.Combine(directory.FullName, "temp.zip"));
var progressInfo =
    new ProgressBarInfo(
        $"{DateTime.Now:dd-MM-yyyy HH:mm:ss.ffff}\t[PROGRESS] Descargar base de datos IP2Location");
UiManager.UiImplementation.ShowProgressBar(progressInfo);
try
{
    using (var webClient = new WebClient { Proxy = null })
    {
        var url = "https://www.ip2location.com/download/?token={downloadToken}&file={DatabaseProduct}";
        webClient.DownloadProgressChanged +=
            (sender, args) =>
                progressInfo.ReportProgress(args.ProgressPercentage / 100d);
        using (var autoResetEvent = new AutoResetEvent(false))
        {
            webClient.DownloadFileCompleted += (sender, args) => autoResetEvent.Set();
            webClient.DownloadFileAsync(new Uri(url), zipFile.FullName);
            autoResetEvent.WaitOne();
        }
    }
}
finally
{
    progressInfo.Close();
}

Si cambio la variable URL a un enlace directo, por ejemplo: https://speed.hetzner.de/10GB.bin, entonces el código funciona bien.

Si visito esta URL: https://www.ip2location.com/download/?token=REDACTED&file=DB11LITE, se descargará directamente un archivo con el nombre IP2LOCATION-LITE-DB11.CSV.ZIP.

Esta es la cabecera de respuesta cuando visito la URL en mi navegador:

HTTP/1.1 200 OK
Server: nginx
Date: Mon, 13 Dec 2021 23:22:15 GMT
Content-Type: application/zip
Content-Length: 48726637
Connection: keep-alive
Expires: 0
Cache-Control: must-revalidate, post-check=0, pre-check=0
Pragma: public
Cache-Control: private
Content-Disposition: attachment; filename="IP2LOCATION-LITE-DB11.CSV.ZIP"
Content-Transfer-Encoding: binary
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Referrer-Policy: no-referrer-when-downgrade
Content-Security-Policy: default-src * data: 'unsafe-eval' 'unsafe-inline';frame-ancestors 'self';
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Tags:  ,

Answer

  1. Avatar for davy.ai

    Parece que el problema con el código radica en el hecho de que la URL proporcionada no enlaza directamente al archivo ZIP que se debe descargar. Una posible solución a este problema podría ser utilizar el cliente web para hacer una solicitud a la URL dada y luego buscar a través de su respuesta para encontrar el enlace de descarga directa.

    Una vez que se encuentre el enlace de descarga directa, se puede utilizar el cliente web para descargar el archivo ZIP desde el enlace directo. Sin embargo, es importante tener en cuenta que el enlace de descarga directa puede ser dinámico y cambiar con frecuencia, por lo que el código deberá actualizarse en consecuencia.

    Para lograr esto, se pueden seguir los siguientes pasos:

    1. Utilizar el WebClient para hacer una solicitud a la URL dada.
    2. Analizar la respuesta para encontrar el enlace de descarga directa. Esto puede requerir alguna manipulación de cadenas o análisis del contenido HTML devuelto por el servidor.
    3. Utilizar el WebClient para descargar el archivo ZIP desde el enlace de descarga directa.

    Un ejemplo de cómo se podría implementar esto en C# utilizando la biblioteca HtmlAgilityPack para analizar la respuesta HTML:

    var url = "https://www.ip2location.com/download/?token=OCULTO&file=DB11LITE";
    
    var webClient = new WebClient();
    var response = webClient.DownloadString(url);
    var htmlDoc = new HtmlDocument();
    htmlDoc.LoadHtml(response);
    
    // Encontrar el enlace de descarga en el HTML utilizando el atributo href u otro identificador
    var downloadLink = htmlDoc.DocumentNode.Descendants("a")
        .FirstOrDefault(a => a.Attributes["href"].Value.EndsWith(".zip"))?.Attributes["href"].Value;
    
    if (!string.IsNullOrEmpty(downloadLink))
    {
        var zipFile = new FileInfo(Path.Combine(directory.FullName, "temp.zip"));
        var progressInfo = new ProgressBarInfo($"{DateTime.Now:dd-MM-yyyy HH:mm:ss.ffff}\t[PROGRESO] Descargar base de datos IP2Location");
        UiManager.UiImplementation.ShowProgressBar(progressInfo);
    
        try
        {
            using (var webClient2 = new WebClient { Proxy = null })
            {
                webClient2.DownloadProgressChanged +=
                    (sender, args) => progressInfo.ReportProgress(args.ProgressPercentage / 100d);
                using (var autoResetEvent = new AutoResetEvent(false))
                {
                    webClient2.DownloadFileCompleted += (sender, args) => autoResetEvent.Set();
                    webClient2.DownloadFileAsync(new Uri(downloadLink), zipFile.FullName);
                    autoResetEvent.WaitOne();
                }
            }
        }
        finally
        {
            progressInfo.Close();
        }
    }
    else
    {
        // Manejar el error: no se pudo encontrar el enlace de descarga
    }
    

Comments are closed.