web-dev-qa-db-fra.com

En utilisant WebClient en C #, existe-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, 
    @"\<title\b[^>]*\>\s*(?<Title>[\s\S]*?)\</title\>",
    RegexOptions.IgnoreCase).Groups["Title"].Value;

Je souhaite stocker l'URL et le titre de la page. Cependant lorsque vous suivez un lien tel que:

http://tinyurl.com/dbysxp

Je vais clairement vouloir obtenir l'URL vers laquelle je suis redirigé.

[~ # ~] questions [~ # ~]

Existe-t-il un moyen de le faire en utilisant la classe WebClient?

Comment pourrais-je le faire en utilisant HttpResponse et HttpRequest?

41
Matthew Rathbone

Si je comprends la question, c'est beaucoup plus facile que ce que les gens disent - si vous voulez laisser WebClient faire tous les écrous et boulons de la demande (y compris la redirection), mais obtenez ensuite l'URI de réponse réelle à à la fin, vous pouvez sous-classer 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;
    }
}

Utilisez simplement MyWebClient partout où vous auriez utilisé WebClient. Après avoir effectué tout appel WebClient que vous deviez faire, vous pouvez simplement utiliser ResponseUri pour obtenir l'URI redirigé réel. Vous devrez également ajouter un remplacement similaire pour GetWebResponse (demande WebRequest, résultat IAsyncResult)), si vous utilisiez le contenu asynchrone.

66
Will Dean

Je sais que c'est déjà une réponse à une question, mais cela fonctionne assez bien pour moi:

 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);

À votre santé.! ;)

16
WhySoSerious

Avec un HttpWebRequest , vous définiriez la propriété AllowAutoRedirect sur false. Dans ce cas, toute réponse avec un code d'état compris entre 300 et 399 ne sera pas automatiquement redirigée.

Vous pouvez ensuite obtenir la nouvelle URL à partir des en-têtes de réponse, puis créer une nouvelle instance de HttpWebRequest dans la nouvelle URL.

Avec la classe WebClient , je doute que vous puissiez le changer tout de suite afin qu'il n'autorise pas les redirections. Vous pouvez dériver une classe de la classe WebClient, puis remplacer les méthodes GetWebRequest et GetWebResponse pour modifier les instances WebRequest / WebResponse renvoyées par l'implémentation de base; s'il s'agit d'un HttpWebRequest, définissez la propriété AllowAutoRedirect sur false. Sur la réponse, si le code d'état est compris entre 300 et 399, émettez une nouvelle demande.

Cependant, je ne sais pas si vous pouvez émettre une nouvelle demande à partir des méthodes GetWebRequest/GetWebResponse, donc il serait peut-ê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
casperOne

J'ai obtenu 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
Stephan Unrau

Dans le cas où vous n'êtes intéressé que par l'URI de redirection, 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 reviendra

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

Veuillez noter : L'instruction using (ou une dernière response.close()) est essentielle. Voir MSDN Library pour plus de détails. Sinon, vous risquez de manquer de connexions ou d'obtenir un délai d'expiration lorsque vous exécutez ce code plusieurs fois.

2
JimiLoe

HttpWebRequest.AllowAutoRedirect peut être défini sur false. Ensuite, vous devrez manuellement http codes d'état dans la plage 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
Arnshea