2012-01-20 14 views
26

Me he encontrado con un comportamiento curioso de las sesiones ASP. Puede obligar a un controlador a estar fuera de la sesión del usuario; deseo poder hacer esto para que se puedan ejecutar varias solicitudes al mismo tiempo y usar una sesión hace que se ejecuten de forma consecutiva.Escribiendo en una sesión de solo lectura en MVC 3+

Desactivación de obras de estado de sesión como se esperaba:

[SessionState(SessionStateBehavior.Disabled)] 
public class SampleController : Controller 
{ 
    public ActionResult Test() 
    { 
     // Access to the session should be denied 
     object test = Session["test"]; 
     return Content(test); 
    } 
} 

El ir a ~/muestra/prueba arrojarán un System.Web.HttpException, como se esperaba. Sin embargo, las sesiones de sólo lectura parecen comportarse de forma un poco extraña:

[SessionState(SessionStateBehavior.ReadOnly)] 
public class SampleController : Controller 
{ 
    public ActionResult Test() 
    { 
     // Read from the session should be fine 
     object test = Session["test"]; 
     return Content(test); 
    } 

    public ActionResult SetTest(string value) 
    { 
     // Write to the session should fail 
     Session["test"] = value; 

     // Read it back from the session 
     object test = Session["test"]; 
     return Content(test); 
    } 
} 

Así que ahora espero ~/muestra/prueba funcione, y lo hace. Lo extraño es que el conjunto también: voy a ~/Sample/SetTest? Value = foo y no lanza una excepción, de hecho devuelve "foo". Si llamo a ~/Sample/SetTest? Value = bar y luego ~/Sample/Test Obtengo "bar", lo que indica que la sesión se ha escrito en.

Así que en un SessionStateBehavior.ReadOnly he escrito con éxito en la sesión y leí mi valor de nuevo.

Creo que esto podría ser debido a una de tres cosas:

  • En MVC 3 [SessionState(SessionStateBehavior.ReadOnly)] se rompe/ignorado.
  • El [SessionState] se anula cuando la sesión se escribe y se puede escribir.
  • En realidad, SessionStateBehavior.ReadOnly indica algún tipo de acceso sucio/optimista.

¿Alguien puede confirmarlo?

Sospecho que el último es verdadero, basado en el custom session provider documentation - si es así ¿cómo funciona la implementación? ¿La escritura en una sesión de "solo lectura" arriesga errores de concurrencia (es decir, la última escritura gana) o corre el riesgo de sesiones corruptas y excepciones de ruptura?

actualización

Parece que este es por diseño (de Microsoft's docs):

Tenga en cuenta que incluso si el atributo EnableSessionState se marca como de sólo lectura, otras páginas ASP.NET en la misma la aplicación puede escribir en el almacén de sesiones, por lo que una solicitud de datos de sesión de solo lectura de la tienda podría terminar esperando a que se liberen los datos bloqueados.

Parece que la segunda opción anterior es lo que realmente hace: la sesión está bloqueada y el modo ha cambiado a escriturable.

Respuesta

9

~/muestra/settest? Valor = foo

Si no arrojará ningún error, pero también no persistió la sesión al final de la solicitud.Por diseño, cualquier cosa que escriba en la sesión se actualiza (solo si la sesión es grabable) al final del ciclo de vida de la solicitud.

En mi prueba ~/Sample/Test no se devuelve nada.

Creo que deberían haber fallado rápido aquí cuando la sesión es de solo lectura.

Por cierto necesita ser reescrito

string test = (string)this.Session["test"]; 
+0

Hmm su muestra, la muestra que aquí se simplifica código para lo que estoy haciendo, pero me estoy haciendo la sesión escrito a - pidiendo _ ~/muestra/settest ? value = foo_ y luego _ ~/Sample/Test_ devuelve "foo" para mí. Realmente debería haber un error, y si no solo no puede guardar la sesión, pero definitivamente me está ahorrando. – Keith

+0

Tiene razón, mi muestra en la pregunta no puede escribir en la sesión, como se esperaba. La pregunta es por qué mi aplicación todavía puede escribir en ella. Voy a averiguar qué es diferente y actualizar la pregunta ... – Keith

+0

como mencioné en mi respuesta anterior, no están fallando rápidamente cuando la sesión es de solo lectura y cuando la actualizas. Framework simplemente ignora la actualización de la sesión al final de la solicitud. Mientras tanto, te permiten modificar la estructura de la sesión de todos modos te gusta. – chandmk

Cuestiones relacionadas