Question

Considérons le cas suivant:

  • Un serveur web est en cours d'exécution un .NET application avec <sessionState cookieless="AutoDetect" />.
  • Un client est l'Affichage des données à l'aide d'un simple HttpWebRequest (pas de cookies).

Cette apparemment simple cas des causes majeures de l'échec.

Depuis .NET ne peut pas déterminer si la demande de l'agent (HttpWebRequest) prend en charge les cookies, il répond à la requête POST avec un 302 Found rediriger vers le même emplacement avec:

  • un cookie nommé AspxAutoDetectCookie dans la réponse
  • un paramètre de requête nommée AspxAutoDetectCookie dans le transmis emplacement

La demande de l'agent est alors censé demander au nouvel emplacement, qui HttpWebRequest n'.Lors de l' .NET voit AspxAutoDetectCookie dans la chaîne de requête, il sait que c'est un re-demande, et il peut déterminer si les cookies sont pris en charge par voir si un cookie nommé AspxAutoDetectCookie est dans les en-têtes de requête.

Le problème est que la plupart requérant agents (navigateurs web, HttpWebRequest) traiter un 302 Found comme si c'est un 303 Voir les Autres et de faire la demande d'un GET, quelle que soit la méthode HTTP d'origine!Toutes les données envoyées dans le POST initial demande n'est pas transmise.

La bonne réponse devrait être une 307 Redirection Temporaire, qui ne modifie pas la méthode de la requête.(Une requête POST à l'emplacement X redirige vers une POST demande d'emplacement Y.)

Est-il possible de modifier ce comportement .NET donc, après les demandes ne sont pas détruits?

Informations sur 3xx redirection

Était-ce utile?

La solution

La seule solution que je vois est d'ajouter AspxAutoDetectCookie=1 pour toutes les requêtes POST.

De cette façon, ASP.NET ne sera jamais rediriger la demande et nous pouvons esquiver les 302 vs 307 question tout à fait.Si les témoins sont intégrés dans la demande, ASP.NET va détecter que les cookies sont pris en charge, et si les cookies ne sont pas intégrés, il va supposer qu'ils ne le sont pas.

Autres conseils

Existe-il des problèmes dans l'utilisation de cookieless="UseDeviceProfile"?Vous pouvez l'utiliser comme une solution de rechange.

Vous voyez aussi la question si cookiless=true.Vous m'a vraiment aidé à sortir.Je ne pouvais même pas comprendre ce qui est à l'origine de ce problème jusqu'à ce que j'ai enlevé la ligne sessionstate cookilesss de vrai de mon web.config, vu le problème fixe, googlé mes résultats et trouvé cette page.Vous a aidé à expliquer pourquoi la suppression de cette ligne a résolu le problème.Pouvez-vous laissez-moi savoir si vous trouvez une solution qui n'implique pas de changer la façon dont j'utilise l'état de session?

Je Sais que le fil est vieux, mais, une autre solution viable est de créer et de HTTP Module de fixer http post sur cookieless.

Voici celui que j'utilise

            using System;
            using System.Collections.Specialized;
            using System.Web;
            using System.Web.SessionState;
            using System.IO;
            using System.Text;

            namespace CustomModule
            {
              public sealed class CookielessPostFixModule : IHttpModule
              {
                public void Init (HttpApplication application)
                {
                  application.EndRequest += new
                              EventHandler(this.Application_EndRequest);
                }
                private string ConstructPostRedirection(HttpRequest req,
                                                        HttpResponse res)
                {
                  StringBuilder build = new StringBuilder();
                  build.Append(
              "<html>\n<body>\n<form name='Redirect' method='post' action='");
                  build.Append(res.ApplyAppPathModifier(req.Url.PathAndQuery));
                  build.Append("' id='Redirect' >");
                  foreach (object obj in req.Form)
                  {
                    build.Append(string.Format(
              "\n<input type='hidden' name='{0}' value = '{1}'>",
                      (string)obj,req.Form[(string)obj]));
                  }
                  build.Append(
              "\n<noscript><h2>Object moved <input type='submit' value='here'></h2></noscript>");
                  build.Append(@"</form>"+
                  "<script language='javascript'>"+
                  "<!--"+
                  "document.Redirect.submit();"+
                  "// -->"+
                  "</script>");
                  build.Append("</body></html>");
                  return build.ToString();
                }
                private bool IsSessionAcquired
                {
                  get
                  {
                    return (HttpContext.Current.Items["AspCookielessSession"]!=null && 
                    HttpContext.Current.Items["AspCookielessSession"].ToString().Length>0);
                  }
                }
                private string ConstructPathAndQuery(string[] segments)
                {
                  StringBuilder build = new StringBuilder(); 

                  for (int i=0;i<segments.Length;i++)
                  {
                    if (!segments[i].StartsWith("(") 
                             && !segments[i].EndsWith(")"))
                      build.Append(segments[i]);
                  }
                  return build.ToString();
                }
                private bool IsCallingSelf(Uri referer,Uri newpage)
                {
                  if(referer==null || newpage==null)
                    return false;
                  string refpathandquery = ConstructPathAndQuery(
                                                    referer.Segments);
                  return refpathandquery == newpage.PathAndQuery;
                }
                private bool ShouldRedirect
                {
                  get
                  {
                    HttpRequest req = HttpContext.Current.Request;

                    return (!IsSessionAcquired
                                && req.RequestType.ToUpper() == "POST"
                      && !IsCallingSelf(req.UrlReferrer,req.Url));
                  }
                }
                private void Application_EndRequest(Object source, EventArgs e)
                {
                  HttpRequest req = HttpContext.Current.Request;
                  HttpResponse res = HttpContext.Current.Response;
                  if (!ShouldRedirect) return;
                  res.ClearContent();
                  res.ClearHeaders();
                  res.Output.Flush();
                  char[] chr = ConstructPostRedirection(req,res).ToCharArray();
                  res.Write(chr,0,chr.Length);
                }
                public void Dispose()
                {}
              }
            }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top