Frage

Betrachten Sie den folgenden Fall:

  • Ein Web-Server eine .NET-Anwendung mit <sessionState cookieless="AutoDetect" /> ausgeführt wird.
  • Ein Client ist POSTen Daten, die ihm ein einfaches HttpWebRequest mit (keine Cookies).

Dieser scheinbar einfache Fall verursacht schwerwiegenden Fehler.

Da .NET kann nicht feststellen, ob der anfragende Agent (HttpWebRequest) unterstützt Cookies, es auf die Anforderung POST antwortet mit einer 302 gefunden Umleitung auf die gleiche Stelle mit:

  • ein Cookie namens AspxAutoDetectCookie in der Antwort
  • eine Abfrage Parameter namens AspxAutoDetectCookie in der weitergeleiteten Lage

Der anfragende Agent soll dann die neue Position beantragen, die HttpWebRequest tut. Wenn .NET AspxAutoDetectCookie in dem Query-String sieht, es weiß dies eine erneute Anforderung ist, und es kann bestimmen, ob Cookies durch Sehen unterstützt werden, wenn ein Cookie namens AspxAutoDetectCookie ist in den Request-Header.

Das Problem ist, dass die meisten anfordernden Agenten (Web-Browser, HttpWebRequest) behandeln, um eine 302 gefunden, als ob es sich um ein 303 See Other ist und die Wieder Anforderung eine GET machen, unabhängig von der ursprünglichen HTTP-Methode! Alle Daten in der Anfangs POST-Anforderung gesendet wird nicht weitergeleitet.

Die richtige Antwort sollte ein 307 Temporary Redirect sein, die nicht die Request-Methode ändert. (A POST-Anforderung an Stelle X Umleitungen zu einer POST Anfrage an Position Y.)

Gibt es eine Möglichkeit, dieses Verhalten in .NET zu ändern, so POST-Anfragen nicht zerstört werden?

Informationen auf 3xx Umleitung

War es hilfreich?

Lösung

Die einzige Lösung, die ich auf diese sehen kann, ist AspxAutoDetectCookie=1 an alle POST-Anfragen anzuhängen.

Auf diese Weise ASP.NET wird nie die Anfrage umleiten und wir können die 302 vs 307 Frage gänzlich ausweichen. Wenn Cookies im Request eingebettet sind, wird ASP.NET erkennen, dass Cookies unterstützt werden, und wenn keine Cookies eingebettet sind, werden sie annehmen, dass sie nicht sind.

Andere Tipps

Gibt es Probleme in cookieless mit = "UseDeviceProfile"? Sie können es als eine Umgehungslösung verwenden.

Sie sehen auch die Frage, ob cookiless = true. Sie half mir wirklich heraus. Ich konnte nicht einmal herausfinden, was das Problem verursacht wurde, bis ich die Linie Einstellung session cookilesss auf true von meinem web.config entfernt, sah das Problem behoben, googeln meine Ergebnisse und diese Seite gefunden. Sie half erklären, warum diese Zeile entfernt das Problem behoben. Können Sie es mich wissen lassen, wenn Sie eine Lösung finden, die nicht die Art, wie ich Sitzungszustand ändert sich bringt verwenden?

Ich weiß, dass der Faden alt ist, aber eine andere praktikable Lösung ist die Schaffung und HTTP-Modul fix http Post über cookieless.

Hier ist eine i Verwendung

            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()
                {}
              }
            }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top