2009-09-29 17 views
9

Tengo un valor que quiero vaild en una sola solicitud. No estoy usando Session, ya que esto haría que el valor sea global para toda la sesión de navegación.ASP.net MVC - variable global con ámbito de solicitud

Así que he puesto este valor en un campo estático de una clase. Genial, pero luego descubrí que esos campos son aún más globales, es decir, ¡permanecen configurados para toda la aplicación! Esto significa que podría haber una interacción aleatoria entre las sesiones de navegación.

Así que la pregunta es: ¿hay un lugar seguro que puedo poner una variable global, que será

  • global a lo largo de la solicitud
  • reinicio después de la solicitud se completa
  • no afectados por cualquier otra petición, ya sea del mismo usuario o por otros usuarios

Gracias Palantir

EDITAR Voy a elaborar. Tengo una pieza de código en mi página maestra, que necesito ocultar en ciertas condiciones, de las cuales soy consciente solo en el controlador. Pensé en el establecimiento de una variable estática en el controlador, que luego se preguntó por la página maestra, pero ahora veo que podría haber una mejor manera ...

Respuesta

10

TempData dura hasta la próxima solicitud como ya se indicó.

Pero también hay otros dos diccionarios con ámbito para la solicitud única.

  • {Controller, ViewPage} .ViewData
  • Context.Items

para comunicarse desde el controlador a la página (maestro) ViewData es probablemente la mejor opción.

+0

'ViewData' y' HttpContext.Items' se eliminan si llama a RedirectToAction durante el ciclo de vida de la solicitud. La única opción en este caso que se conserva para la solicitud redirigida es 'TempData'. Tendría que quitar los artículos que puso allí después de que haya terminado. –

+0

La forma en que 'TempData' funciona ha cambiado desde entonces y ahora' TempData' dura hasta que se vuelve a leer. Entonces, usar 'TempData' para esto podría llevar a que pasen cosas raras. 'ViewData' (y' ViewBag') no funcionan con pasar datos de la acción secundaria a parent (y creo que incluso vista parcial -> vista principal), por lo que usar 'Context.Items' es lo mejor de los 3. – jahu

2

Dos enfoques vienen a la mente:

  1. Crea un controlador base donde estableces esta variable, y luego haz que todos tus controladores hereden de esa.
  2. Use TempData - el problema aquí es que se queda para la próxima solicitud. Pero tal vez sabiendo eso, puede solucionarlo utilizando una clave GUID para determinar que, de hecho, está obteniendo un nuevo valor cuando lo necesita.

Probablemente vaya con 1).

1

La forma más común de acceder a los datos en una página maestra que está configurada en el controlador (acción) es a través de ViewData ["TheDataKey"] = "SomeValue".

23

Use HttpContext.Items - una tienda de caché por solicitud. Consulte this article en 4guysfromrolla para más detalles.

Debería funcionar bien en ASP.NET MVC. Es posible que desee derivar su página maestra de una clase base (ya sea por código subyacente o mediante la directiva Inherits) y tener un método protegido en la clase base que inspeccione HttpContext.Items y lo devuelva, p. true/false dependiendo de si desea mostrar el código condicional.

+1

+1 Respuesta Ah, mucho mejor que mi "Agregar a la cabecera de la solicitud", y además aprendí somefink. –

1

Esto es relativamente fácil y hay varias maneras en que puede hacerlo, dependiendo de cómo funcione su sitio.

Estoy interpretando su solicitud como que desea una propiedad o variable que existe durante la duración de la solicitud y es visible para el controlador, modelo y maestro.

Una propiedad estática es visible para la aplicación actual en ASP esto significa una carga de usuarios que se conectan a la vez, pero no necesariamente todos ellos. IIS generará nuevas aplicaciones ASP a medida que lo necesite.

Así que las formas en las que puede hacer esto:

Puede tener una clase base personalizado para su página principal o una página de código subyacente (como todos los formularios Web rellenan todavía funciona)

Usted puede tener una clase base personalizada para sus controladores.

se puede llegar a una de la otra, así que:

void Page_Init(object sender, EventArgs e) 
{ 
    var ctrl = this.ViewContext.Controller as MyBaseController; 
    if (ctrl != null) 
    { 
     MyLocalProp = ctrl.PropOnMyController; 
    } 
} 

Esta estarán disponibles en el controlador y la página maestra en una base por solicitud.

0

¿Has mirado en el tempData que está conectado a la clase de controlador? es un diccionario simple que conserva su valor a través de una única solicitud. Eso significa que solo se puede acceder a sus datos en el controlador, pero eso no debería ser un problema.

public class MyController : Controller 
{ 
    [AcceptVerbs(HttpVerbs.Get)] 
    public ActionResult MyAction(string id) 
    { 
    this.TempData["Message"] = "YourData"; 
    } 

    [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult MyAction(string Id) 
    { 
    var myData = this.TempData["Message"]; 
    } 
} 

Esto funciona para mí. Lo uso solo para mostrar mensajes de advertencia y cosas así.

Cuestiones relacionadas