1

我正在使用 ASP.NET MVC 4 并且有一种情况,我将一些数据保存在 MasterController 中,因为我想在跨站点导航栏中预加载一些数据。

abstract class MasterController : Controller
{
    FakeObject MyData { get; set; }

    if (this.MyData == null)
    {
        this.MyData = // do something crazy and load lots of data
    }
}

每个控制器都继承自 MasterController

class HomeController : MasterController
{
    ActionResults Index()
    {
        return View();
    }
}

问题是每次回发时,MyData 都会被覆盖。我正在尝试找到一种方法来存储这些数据并在不使用 SessionState 的情况下在 PostBacks 之间检索它。这可以做到吗?也许我对 MasterController 的使用不正确。

我尝试了以下方法,但它不起作用:(

TempData.Add("mydata", MyData);
TempData.Keep("mydata");
4

2 回答 2

1

如果这基本上是静态数据,则可以使用内置缓存。

abstract class MasterController : Controller
{
    public MasterController() { if (Cache["Foo"] == null) Cache["Foo"] = Something; }
}

class HomeController : MasterController
{
    ActionResults Index()
    {
        return View(Cache["Foo"]);
    }
}
于 2012-06-07T04:51:28.007 回答
1

我不确定你在哪里if(String.IsNullOrEmpty...被使用(我认为你缺少一个包含成员;那不是有效的代码。

但是,我认为您可能需要考虑依赖注入和松散耦合,而不是在控制器中硬编码业务逻辑。这里有两个建议。

选项 1:依赖注入和 TempData

public interface IFakeObjectFactory
{
      FakeObject Create();
}

public class FakeObjectFactory : IFakeObjectFactory
{
      public FakeObject Create()
      {
          // create FakeObject
      }
}

然后你的控制器看起来更像这样:

public abstract class MasterController : Controller
{
    protected IFakeObjectFactory FakeObjectFactory { get; private set; }

    private FakeObject _myData;

    protected FakeObject EnsureMyData() 
    {
         if (_myData != null) return _myData;

          _myData = TempData["myData"] as FakeObject ?? FakeObjectFactory.Create();

          TempData["myData"] = _myData;
    }

    protected MasterController(IFakeObjectFactory fakeDataFactory)
    {
        FakeDataFactory = fakeDataFactory;
    }
}


public class HomeController : MasterController
{
    public HomeController(IFakeObjectFactory fakeObjectFactory)
      : base(fakeObjectFactory)
    { }

    ActionResults Index()
    {
        ViewBag.MyData = EnsureMyData();

        return View(); // you could also use MyData as the view model, rather than using ViewBag above. not sure what you need from here.
    }
}

现在,您可以使用 Inversion of Control 容器来创建您的控制器并为您注入依赖项(一些流行的 IoC 是 Ninject 和 Autofac)。如果你觉得你还没有准备好,你总是可以在你的EnsureMyData方法中硬编码创建一个工厂的实例,并去掉 and 中的构造函数HomeController参数MasterController

使用工厂接口和依赖注入的好处是您可以独立于控制器创建、测试和维护工厂。如果需要,您还可以在将来很容易地换出实现。

选项 2:使用静态只读字段

另一个选项(如果MyData是常量)是您可以将其设为 的静态成员MasterController,而不是使用TempData.

public abstract MasterController : Controller
{
    public static readonly FakeData MyData;

    static MasterController()
    {
       // Initialize MyData
    }
}

public HomeController : MasterController
{
    public ActionResult Index()
    {
        ViewBag.MyData = MyData;

        View(); // you could also use MyData as the view model, rather than using ViewBag above. not sure what you need from here.
    }
}

我不推荐这种方法,除非逻辑非常简单,或者您只是不关心并且想要快速而肮脏的东西。测试单例和静态方法是一件很痛苦的事情。

于 2012-06-07T02:40:25.553 回答