txt net form example desde descargar archivo c# file download webclient

c# - form - ¿Cómo verificar si System.Net.WebClient.DownloadData está descargando un archivo binario?



webclient c# (7)

WebClient usar WebClient para descargar un archivo de la web usando una aplicación WinForms. Sin embargo, realmente solo quiero descargar un archivo HTML. Cualquier otro tipo que desee ignorar.

WebResponse.ContentType el WebResponse.ContentType , pero su valor siempre es null .

Alguien tiene alguna idea de lo que podría ser la causa?


¿Podría emitir la primera solicitud con el verbo HEAD y verificar el encabezado de respuesta de tipo de contenido? [editar] Parece que tendrás que usar HttpWebRequest para esto.


Aquí hay un método que usa TCP, sobre el cual se construye http. Volverá cuando esté conectado o después del tiempo de espera (milisegundos), por lo que puede ser necesario cambiar el valor según su situación

var result = false; try { using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { var asyncResult = socket.BeginConnect(yourUri.AbsoluteUri, 80, null, null); result = asyncResult.AsyncWaitHandle.WaitOne(100, true); socket.Close(); } } catch { } return result;


Dada su actualización, puede hacer esto cambiando el .Method en GetWebRequest:

using System; using System.Net; static class Program { static void Main() { using (MyClient client = new MyClient()) { client.HeadOnly = true; string uri = "http://www.google.com"; byte[] body = client.DownloadData(uri); // note should be 0-length string type = client.ResponseHeaders["content-type"]; client.HeadOnly = false; // check ''tis not binary... we''ll use text/, but could // check for text/html if (type.StartsWith(@"text/")) { string text = client.DownloadString(uri); Console.WriteLine(text); } } } } class MyClient : WebClient { public bool HeadOnly { get; set; } protected override WebRequest GetWebRequest(Uri address) { WebRequest req = base.GetWebRequest(address); if (HeadOnly && req.Method == "GET") { req.Method = "HEAD"; } return req; } }

De forma alternativa, puede verificar el encabezado al anular GetWebRespons (), quizás lanzando una excepción si no es lo que quería:

protected override WebResponse GetWebResponse(WebRequest request) { WebResponse resp = base.GetWebResponse(request); string type = resp.Headers["content-type"]; // do something with type return resp; }


Me disculpo por no haber sido muy claro. Escribí una clase contenedora que extiende WebClient. En esta clase de contenedor, agregué el contenedor de cookies y expuse la propiedad de tiempo de espera para WebRequest.

Estaba usando DownloadDataAsync () de esta clase contenedora y no pude recuperar el tipo de contenido de WebResponse de esta clase contenedora. Mi intención principal es interceptar la respuesta y determinar si es de naturaleza text / html. Si no es así, abortaré esta solicitud.

Logré obtener el tipo de contenido después de anular el método WebClient.GetWebResponse (WebRequest, IAsyncResult).

La siguiente es una muestra de mi clase contenedora:

public class MyWebClient : WebClient { private CookieContainer _cookieContainer; private string _userAgent; private int _timeout; private WebReponse _response; public MyWebClient() { this._cookieContainer = new CookieContainer(); this.SetTimeout(60 * 1000); } public MyWebClient SetTimeout(int timeout) { this.Timeout = timeout; return this; } public WebResponse Response { get { return this._response; } } protected override WebRequest GetWebRequest(Uri address) { WebRequest request = base.GetWebRequest(address); if (request.GetType() == typeof(HttpWebRequest)) { ((HttpWebRequest)request).CookieContainer = this._cookieContainer; ((HttpWebRequest)request).UserAgent = this._userAgent; ((HttpWebRequest)request).Timeout = this._timeout; } this._request = request; return request; } protected override WebResponse GetWebResponse(WebRequest request) { this._response = base.GetWebResponse(request); return this._response; } protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result) { this._response = base.GetWebResponse(request, result); return this._response; } public MyWebClient ServerCertValidation(bool validate) { if (!validate) ServicePointManager.ServerCertificateValidationCallback += delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; }; return this; } }


No estoy seguro de la causa, pero quizás aún no has descargado nada. Esta es la manera perezosa de obtener el tipo de contenido de un archivo / página remota (no he comprobado si esto es eficiente en el cable. Por lo que sé, puede descargar grandes cantidades de contenido)

Stream connection = new MemoryStream(""); // Just a placeholder WebClient wc = new WebClient(); string contentType; try { connection = wc.OpenRead(current.Url); contentType = wc.ResponseHeaders["content-type"]; } catch (Exception) { // 404 or what have you } finally { connection.Close(); }


Su pregunta es un poco confusa: si está usando una instancia de la clase Net.WebClient, Net.WebResponse no entra en la ecuación (aparte del hecho de que es de hecho una clase abstracta, y estaría usando una implementación concreta como HttpWebResponse, como se señala en otra respuesta).

De todos modos, al usar WebClient, puede lograr lo que desea haciendo algo como esto:

Dim wc As New Net.WebClient() Dim LocalFile As String = IO.Path.Combine(Environment.GetEnvironmentVariable("TEMP"), Guid.NewGuid.ToString) wc.DownloadFile("http://example.com/somefile", LocalFile) If Not wc.ResponseHeaders("Content-Type") Is Nothing AndAlso wc.ResponseHeaders("Content-Type") <> "text/html" Then IO.File.Delete(LocalFile) Else ''//Process the file End If

Tenga en cuenta que debe verificar la existencia del encabezado Content-Type, ya que no se garantiza que el servidor lo devuelva (aunque la mayoría de los servidores HTTP modernos siempre lo incluirán). Si no hay un encabezado Content-Type presente, puede recurrir a otro método de detección HTML, por ejemplo, abrir el archivo, leer los primeros caracteres 1K o menos en una cadena y ver si contiene la subcadena <html>

También tenga en cuenta que esto es un poco derrochador, ya que siempre transferirá el archivo completo, antes de decidir si lo quiere o no. Para solucionarlo, cambiar a las clases Net.HttpWebRequest / Response puede ayudar, pero si el código adicional vale la pena depende de su aplicación ...


WebResponse es una clase abstracta y la propiedad ContentType se define en clases heredadas. Por ejemplo, en el objeto HttpWebRequest este método está sobrecargado para proporcionar el encabezado de tipo de contenido. No estoy seguro de qué instancia de WebResponse utiliza el WebClient. Si SOLO desea archivos HTML, lo mejor que puede hacer es usar el objeto HttpWebRequest directamente.