我正在使用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的情况下在PostBack之间检索它。可以这样做吗?也许我对MasterController的使用不正确。
我尝试了以下操作,但它不起作用:(
TempData.Add("mydata", MyData);
TempData.Keep("mydata");
答案 0 :(得分: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
方法中硬编码创建工厂实例,并删除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.
}
}
这种方法我不推荐,除非逻辑很简单,或者你只是不关心并想要快速和肮脏的东西。测试单例和静态方法是一个痛苦的对接。
答案 1 :(得分:1)
如果这基本上是静态数据,则可以使用内置缓存。
abstract class MasterController : Controller
{
public MasterController() { if (Cache["Foo"] == null) Cache["Foo"] = Something; }
}
class HomeController : MasterController
{
ActionResults Index()
{
return View(Cache["Foo"]);
}
}