2009-07-31 5 views
24

Je souhaite acheminer par tunnel une requête HTTP de mon serveur vers un serveur distant, en passant par tous les cookies. Donc, je crée un nouvel objet HttpWebRequest et je veux y placer des cookies.Envoi de cookies à l'aide de HttpCookieCollection et de CookieContainer

HttpWebRequest.CookieContainer est le type System.Net.CookieContainer qui contient System.Net.Cookies.

Sur mon objet requête entrante:

HttpRequest.Cookies est de type System.Web.HttpCookieCollection qui détient System.Web.HttpCookies.

Fondamentalement, je veux être en mesure de les affecter les uns aux autres, mais les différents types le rend impossible. Dois-je les convertir en copiant leurs valeurs, ou existe-t-il un meilleur moyen?

Répondre

34

Voici le code que je l'ai utilisé pour transférer les objets cookie de la requête entrante à la nouvelle HttpWebRequest ... (« myRequest » est le nom de mon HttpWebRequest objet.)

HttpCookieCollection oCookies = Request.Cookies; 
for (int j = 0; j < oCookies.Count; j++) 
{ 
    HttpCookie oCookie = oCookies.Get(j); 
    Cookie oC = new Cookie(); 

    // Convert between the System.Net.Cookie to a System.Web.HttpCookie... 
    oC.Domain = myRequest.RequestUri.Host; 
    oC.Expires = oCookie.Expires; 
    oC.Name  = oCookie.Name; 
    oC.Path  = oCookie.Path; 
    oC.Secure = oCookie.Secure; 
    oC.Value = oCookie.Value; 

    myRequest.CookieContainer.Add(oC); 
} 
+0

Je pense que cette technique fonctionnera, mais j'espérais vraiment une solution qui n'impliquerait pas la copie de chaque valeur. – Mike

+0

quoi avec l'essai avec la prise vide? – CRice

+0

bon point, ça a été enlevé. – David

1

Le suggéré de David est le bon. Vous devez copier. Il suffit de créer simplement une fonction pour copier à plusieurs reprises. HttpCookie et l'objet Cookie est créé pour s'assurer que nous pouvons différencier à la fois dans sa fonctionnalité et d'où elle vient. HttpCookie utilisé entre l'utilisateur et votre proxy Cookie est utilisé entre votre proxy et votre serveur web distant. HttpCookie a moins de fonctionnalités car le cookie est originaire de vous et vous savez comment le gérer. Cookie vous permet de gérer les cookies reçus du serveur Web. Comme CookieContainer, il peut être utilisé pour gérer le domaine, le chemin et l'expiration.

Le côté serveur et côté serveur est différent et pour le connecter, vous devez le convertir. Dans votre cas, il s'agit simplement d'assignation directe.

Notez que CookieContainer a un bogue sur la méthode .Add (Cookie) et .GetCookies (uri).

Voir les détails et fixer ici:

http://dot-net-expertise.blogspot.com/2009/10/cookiecontainer-domain-handling-bug-fix.html

CallMeLaNN

3

J'ai eu besoin de le faire aujourd'hui pour un site SharePoint qui utilise des formulaires authentification basée sur (FBA). Si vous essayez d'appeler une page d'application sans cloner les cookies et assigner un objet CookieContainer, la requête échouera.

J'ai choisi de faire abstraction du travail à cette méthode d'extension pratique:

public static CookieContainer GetCookieContainer(this System.Web.HttpRequest SourceHttpRequest, System.Net.HttpWebRequest TargetHttpWebRequest) 
    { 
     System.Web.HttpCookieCollection sourceCookies = SourceHttpRequest.Cookies; 
     if (sourceCookies.Count == 0) 
      return null; 
     else 
     { 
      CookieContainer cookieContainer = new CookieContainer(); 
      for (int i = 0; i < sourceCookies.Count; i++)     
      { 
       System.Web.HttpCookie cSource = sourceCookies[i]; 
       Cookie cookieTarget = new Cookie() { Domain = TargetHttpWebRequest.RequestUri.Host, 
                Name = cSource.Name, 
                Path = cSource.Path, 
                Secure = cSource.Secure, 
                Value = cSource.Value }; 
       cookieContainer.Add(cookieTarget); 
      } 
      return cookieContainer; 
     } 
    } 

Vous pouvez alors appeler cela de tout objet HttpRequest avec une cible d'objet HttpWebRequest comme paramètre, par exemple:

HttpWebRequest request;     
request = (HttpWebRequest)WebRequest.Create(TargetUrl); 
request.Method = "GET"; 
request.Credentials = CredentialCache.DefaultCredentials; 
request.CookieContainer = SourceRequest.GetCookieContainer(request);     
request.BeginGetResponse(null, null); 

où TargetUrl est l'URL de la page que je suis après et SourceRequest est le HttpRequest de la page que je suis actuellement, récupéré via Page.Request.