¿Cómo persistir los datos en la memoria en el controlador MVC?

Por favor, mire la siguiente acción. Cuando el usuario navega por primera vez, crea un objeto, luego mientras navega en la página, accede nuevamente a la Acción pero a través de la solicitud Ajax y los datos desaparecen (worksheets = null).

    private static List<Worksheet> worksheets;
    public ActionResult DoTest()
    {
        if (Request.IsAjaxRequest())
        {
            return PartialView("_Problems", worksheets[1]);
        }

        // first time
        worksheets = new List<Worksheet>()
        {
            new Worksheet("Hoja 1", ...),
            new Worksheet("Hoja 2", ...)
        };
        return View(worksheets[0]);
    }

Mi primera solución fue establecer las hojas de trabajo variables en estáticas, pero supuse que no era una buena práctica. ¿Estoy haciendo un buen camino o hay otros tweeks?

preguntado el 02 de enero de 13 a las 19:01

3 Respuestas

Manténgase alejado de las variables estáticas, especialmente si los datos dependen del usuario. Podrías aprovechar la Sesión ASP.NET objeto.

Esto se puede hacer fácilmente en su caso cambiando el campo de su hoja de trabajo a una propiedad que almacene su valor en el objeto Sesión. De esta manera, estará disponible en próximas convocatorias. Ejemplo:

  private List<Worksheet> worksheets
  {
    get{ return Session["worksheets"] as List<Worksheet>;}
    set{ Session["worksheets"] = value; }
  }

  public ActionResult DoTest()
  {
      if (Request.IsAjaxRequest())
      {
        return PartialView("_Problems", worksheets[1]);
      }

      // first time
      worksheets = new List<Worksheet>()
      {
          new Worksheet("Hoja 1", ...),
          new Worksheet("Hoja 2", ...)
      };
      return View(worksheets[0]);
  }

Respondido el 02 de enero de 13 a las 19:01

Gracias Ulises, funcionó! Solo una respuesta, me gusta interesante cómo funciona el diccionario de sesión, imagina que el navegador está cerrado. ¿Cómo puedo persistir la sesión hasta 60 minutos inclusive si el navegador está cerrado? - Zona Darf

@DarfZon El valor predeterminado del objeto Sesión es 20 min (puede cambiar esto en el archivo de configuración). A menos que lo borre antes, permanecerá vivo en el lado del servidor incluso si el usuario cierra el navegador; sin embargo, esto puede causar que el servidor asigne un objeto de sesión diferente al usuario (dependiendo de su mecanismo de autenticación) - Ulises

La instancia de su controlador no persiste entre las solicitudes (es por eso que hacer que las hojas de trabajo sean estáticas funciona, pero mantenerlas no estáticas no lo hace; el objeto solo se completa en una solicitud que no es AJAX debido a su declaración if).

Una opción es llenar el objeto sin importar cómo llegue la solicitud y luego usar la instrucción if para decidir qué elemento devolver. La otra solución (probablemente mejor) es usar la sesión, como mencionó Ulises.

Respondido el 02 de enero de 13 a las 19:01

En ASP.NET Core Session no admite el tipo de datos genéricos, deberá agregar esta extensión

using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;

public static class SessionExtensions
{
    public static void Set<T>(this ISession session, string key, T value)
    {
        session.SetString(key, JsonConvert.SerializeObject(value));
    }

    public static T Get<T>(this ISession session,string key)
    {
        var value = session.GetString(key);
        return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
    }
}

y para usarlo:

public IActionResult SetDate()
{
    // Requires you add the Set extension method mentioned in the article.
    HttpContext.Session.Set<DateTime>(SessionKeyDate, DateTime.Now);
    return RedirectToAction("GetDate");
}

public IActionResult GetDate()
{
    // Requires you add the Get extension method mentioned in the article.
    var date = HttpContext.Session.Get<DateTime>(SessionKeyDate);
    var sessionTime = date.TimeOfDay.ToString();
    var currentTime = DateTime.Now.TimeOfDay.ToString();

    return Content($"Current time: {currentTime} - "
                 + $"session time: {sessionTime}");
}

Respondido 31 Oct 17, 08:10

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.