Reputation: 6378
Please look at the below action. When the user navigate the first time, creates a object, then while he navigates in the page, access again to the Action but through Ajax request and the data disappers (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]);
}
My first solution was set the variable worksheets to static, but I supposed this is not a good practice. Am I doing a good way or are there another tweeks?
Upvotes: 7
Views: 14418
Reputation: 563
In ASP.NET Core Session doesn't support Generic data type you'll need to add this extension
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);
}
}
and to use it:
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}");
}
Upvotes: 0
Reputation: 197
The instance of your controller does not persist across requests (This is why making worksheets static works, but keeping it non-static does not -- the object is only populated on a non-AJAX request due to your if statement).
One option is to populate the object no matter how the request comes in and then use the if statement to decide which item to return. The other (probably better) solution is to use the session, as Ulises mentioned.
Upvotes: 1
Reputation: 13429
Stay away from static variables, especially if the data is user-dependent. You could take advantage of the ASP.NET Session object.
This can be easily done in your case by changing your worksheets field to a property that stores its value in the Session object. This way, it will be available on subsequent calls. Example:
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]);
}
Upvotes: 11