如何将数据保存在MVC控制器的内存中?

时间:2013-01-02 19:29:41

标签: asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-4

请看下面的动作。当用户第一次导航时,创建一个对象,然后当他在页面中导航时,再次访问Action但是通过Ajax请求和数据disapper(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]);
    }

我的第一个解决方案是将变量工作表设置为静态,但我认为这不是一个好习惯。我是在做一个好方法还是有其他的推文?

3 个答案:

答案 0 :(得分:9)

远离静态变量,尤其是在数据与用户相关的情况下。您可以利用ASP.NET Session对象。

通过将工作表字段更改为在Session对象中存储其值的属性,可以轻松完成此操作。这样,可以在后续通话中使用。例如:

  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]);
  }

答案 1 :(得分:1)

控制器的实例不会在请求之间保持不变(这就是为什么使工作表静态工作,但保持非静态不起作用 - 由于你的if语句,该对象仅填充在非AJAX请求上)。

一种选择是填充对象,无论请求如何进入,然后使用if语句来决定返回哪个项目。另一个(可能更好的)解决方案是使用会话,正如Ulises所提到的那样。

答案 2 :(得分:0)

在ASP.NET核心会话中不支持通用数据类型,您需要添加此扩展

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);
    }
}

并使用它:

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}");
}