7

Considere el siguiente caso:peticiones POST cuando fallan <sessionState sin cookies = "detección automática" /> se establece

  • Un servidor Web se está ejecutando una aplicación .NET con <sessionState cookieless="AutoDetect" />.
  • Un cliente está PUBLICANDO datos utilizando un simple HttpWebRequest (sin cookies).

Esta aparentemente simple caso de las principales causas fracaso.

Desde .NET no se puede determinar si el agente solicitante (HttpWebRequest) soporta cookies, que responde a la solicitud POST con una redirección 302 encontrado en la misma ubicación con:

  • una cookie nombrado en el AspxAutoDetectCookie
  • respuesta
  • se supone entonces un parámetro de consulta con nombre AspxAutoDetectCookie en la ubicación remitido

el agente solicitante para solicitar la nueva ubicación, lo que hace HttpWebRequest. Cuando .NET ve AspxAutoDetectCookie en la cadena de consulta, sabe que se trata de una nueva solicitud, y puede determinar si las cookies son compatibles al ver si una cookie llamada AspxAutoDetectCookie se encuentra en los encabezados de las solicitudes.

El problema es que la mayoría de los agentes solicitantes (navegadores web, HttpWebRequest) tratan un 302 Encontrado como si fuera un 303 Consulte Otro y haga que la solicitud vuelva a ser OBTENIDA, ¡independientemente del método HTTP original! Cualquier información enviada en la solicitud POST inicial no se reenvía.

La respuesta correcta debe ser un redireccionamiento temporal 307, que no cambia el método de solicitud. (Una solicitud POST a la ubicación X redirige a una solicitud POST a la ubicación Y.)

¿Hay alguna manera de cambiar este comportamiento en .NET para que las solicitudes POST no se destruyan?

Information on 3xx redirection

Respuesta

1

La única solución que puedo ver a este es anexar AspxAutoDetectCookie=1 a todas las peticiones POST.

De esta manera, ASP.NET nunca redirigirá la solicitud y podemos esquivar la pregunta 302 contra 307 por completo. Si las cookies están incrustadas en la solicitud, ASP.NET detectará que las cookies son compatibles, y si no se incluyen cookies, asumirá que no lo son.

+0

No funciona aquí al menos. Aún descarta los datos de la publicación. – Karlth

+0

Funciona si agregamos el encabezado: 'Cookie: AspxAutoDetectCookie = 1'. – Artyom

0

¿Hay algún problema en el uso de cookies = "UseDeviceProfile"? Puede usarlo como una solución alternativa.

+0

Por desgracia, no puedo usar esa configuración. Tiene que funcionar con "AutoDetect". – Anton

0

También aparece el problema si cookiless = true. Realmente me ayudaste. Ni siquiera podía averiguar qué estaba causando este problema hasta que eliminé la línea que establece sessionstate cookilesss en true desde mi web.config, vi el problema solucionado, busqué en Google mis resultados y encontré esta página. Usted ayudó a explicar por qué eliminar esta línea solucionó el problema. ¿Me puede avisar si encuentra una solución que no implique cambiar la forma en que uso el estado de la sesión?

0

Sé que el hilo es antiguo pero, otra solución viable es crear un módulo HTTP para corregir la publicación http en cookies.

Aquí es que yo uso

  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() 
       {} 
       } 
      } 
Cuestiones relacionadas