Utiliser WebClient dans C# y a-t-il un moyen d'obtenir L'URL d'un site après avoir été redirigé?

en utilisant la classe WebClient je peux obtenir le titre d'un site Web assez facilement:

WebClient x = new WebClient();    
string source = x.DownloadString(s);
string title = Regex.Match(source, 
    @"<titleb[^>]*>s*(?<Title>[sS]*?)</title>",
    RegexOptions.IgnoreCase).Groups["Title"].Value;

je veux stocker l'URL et le titre de la page. Toutefois, lorsque vous suivez un lien tel que:

http://tinyurl.com/dbysxp

je vais clairement vouloir obtenir L'Url à laquelle je suis redirigé.

QUESTIONS

Est-il un moyen de le faire avec la classe WebClient ?

comment utiliser HttpResponse et HttpRequest ?

38
demandé sur casperOne 2009-03-27 19:58:12

8 réponses

si je comprends la question, il est beaucoup plus facile que les gens disent-Si vous voulez laisser WebClient faire tous les boulons de la demande( y compris la redirection), mais puis obtenir le réelle URI de réponse à la fin, vous pouvez sous-classe WebClient comme ceci:

class MyWebClient : WebClient
{
    Uri _responseUri;

    public Uri ResponseUri
    {
        get { return _responseUri; }
    }

    protected override WebResponse GetWebResponse(WebRequest request)
    {
        WebResponse response = base.GetWebResponse(request);
        _responseUri = response.ResponseUri;
        return response;
    }
}

il suffit d'utiliser MyWebClient partout où vous auriez utilisé WebClient. Après que vous avez fait N'importe quel WebClient appel que vous avez dû faire, alors vous pouvez juste utiliser Respseuri pour obtenir le vrai URI redirigé. vous devez ajouter un contrôleur similaire pour GetWebResponse(requête WebRequest, résultat IAsyncResult) aussi, si vous utilisez le truc async.

62
répondu Will Dean 2013-05-22 10:33:38

je sais que c'est déjà une question à laquelle on répond, Mais ça me va bien:

 HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://tinyurl.com/dbysxp");
 request.AllowAutoRedirect = false;
 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
 string redirUrl = response.Headers["Location"];
 response.Close();

 //Show the redirected url
 MessageBox.Show("You're being redirected to: "+redirUrl);

santé.! ;)

16
répondu WhySoSerious 2015-08-10 15:20:44

avec un HttpWebRequest , vous définiriez le AllowAutoRedirect propriété à false . Lorsque cela se produit, toute réponse avec un code d'état entre 300-399 ne sera pas automatiquement redirigée.

vous pouvez alors obtenir la nouvelle url à partir des en-têtes de réponse et ensuite créer une nouvelle instance HttpWebRequest à la nouvelle url.

avec le WebClient classe , je doute vous pouvez le changer pour qu'il n'autorise pas les redirections. Ce que vous pourriez faire est de dériver une classe de la classe WebClient et puis de remplacer les GetWebRequest et les GetWebResponse méthodes pour modifier le WebRequest / WebResponse instances où l'implémentation de base retourne; si c'est un HttpWebRequest , alors mettez la propriété AllowAutoRedirect à false . Sur le réponse, si le code de statut est dans la gamme de 300-399, puis émettre une nouvelle demande.

cependant, je ne sais pas si vous pouvez émettre une nouvelle requête à partir des méthodes GetWebRequest / GetWebResponse , donc il pourrait être préférable d'avoir juste une boucle qui s'exécute avec HttpWebRequest / HttpWebResponse jusqu'à ce que toutes les redirections soient suivies.

6
répondu casperOne 2011-11-15 22:45:44

j'ai reçu L'Uri pour la page redirigée et le contenu de la page.

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strUrl);
request.AllowAutoRedirect = true;

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream dataStream = response.GetResponseStream();

strLastRedirect = response.ResponseUri.ToString();

StreamReader reader = new StreamReader(dataStream);              
string strResponse = reader.ReadToEnd();

response.Close();
3
répondu Stephan Unrau 2013-03-21 13:45:43

dans le cas où vous êtes seulement intéressé par la redirection URI, vous pouvez utiliser ce code:

public static string GetRedirectUrl(string url)
{
     HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create(url);
     request.AllowAutoRedirect = false;

     using (HttpWebResponse response = HttpWebResponse)request.GetResponse())
     {
         return response.Headers["Location"];
     }
}

la méthode retournera

  • null-en cas de non-redirection
  • une url relative - en cas de redirection

prendre note : using instruction (ou un final response.close() ) est essentiel. Voir MSDN Library pour plus de détails. Dans le cas contraire, vous pourriez manquer de connexions ou avoir un délai d'attente lors de l'exécution de ce code plusieurs fois.

2
répondu JimiLoe 2015-05-10 13:46:53

HttpWebRequest.AllowAutoRedirect peut être défini à false. Ensuite, vous devez manuellement les codes d'état http dans la gamme 300.

// Create a new HttpWebRequest Object to the mentioned URL.
HttpWebRequest myHttpWebRequest=(HttpWebRequest)WebRequest.Create("http://www.contoso.com");    
myHttpWebRequest.MaximumAutomaticRedirections=1;
myHttpWebRequest.AllowAutoRedirect=true;
HttpWebResponse myHttpWebResponse=(HttpWebResponse)myHttpWebRequest.GetResponse();  
0
répondu Arnshea 2009-03-27 17:07:16

la classe WebClient a une option pour suivre les redirections. Mettez cette option et tout ira bien.

-1
répondu Albert 2009-03-27 17:07:13

Ok c'est vraiment hackish, mais la clé est d'utiliser la propriété HttpWebRequest puis de définir la propriété AllowAutoRedirect à true.

voici un exemple très hacké ensemble

        HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://tinyurl.com/dbysxp");
        req.Method = "GET";
        req.AllowAutoRedirect = true;
        WebResponse response = req.GetResponse();

        response.GetResponseStream();
        Stream responseStream = response.GetResponseStream();

        // Content-Length header is not trustable, but makes a good hint.
        // Responses longer than int size will throw an exception here!
        int length = (int)response.ContentLength;

        const int bufSizeMax = 65536; // max read buffer size conserves memory
        const int bufSizeMin = 8192;  // min size prevents numerous small reads

        // Use Content-Length if between bufSizeMax and bufSizeMin
        int bufSize = bufSizeMin;
        if (length > bufSize)
            bufSize = length > bufSizeMax ? bufSizeMax : length;

        StringBuilder sb;
        // Allocate buffer and StringBuilder for reading response
        byte[] buf = new byte[bufSize];
        sb = new StringBuilder(bufSize);

        // Read response stream until end
        while ((length = responseStream.Read(buf, 0, buf.Length)) != 0)
            sb.Append(Encoding.UTF8.GetString(buf, 0, length));

        string source = sb.ToString();string title = Regex.Match(source, 
        @"\<title\b[^>]*\>\s*(?<Title>[\s\S]*?)\</title\>",RegexOptions.IgnoreCase).Groups["Title"].Value;

enter code here

-1
répondu danswain 2009-03-27 17:17:38