目前我正在覆盖ASP.NET ViewPage的OnLoad事件。这样就可以与所有视图共享一个对象。但我现在需要能够在控制器中访问该对象;最好的方法是什么?
基本上,我想与视图页面和控制器共享一个对象(对于Web应用程序的每个用户来说都是唯一的......所以单例出来了)。
谢谢!
答案 0 :(得分:2)
我不确定您是否希望为整个用户的会话维护对象的引用,或者您是否只希望将其用于单个请求。无论哪种方式,您都可以使用Global.asax将对象放入要使用的控制器和视图的范围:
首先,请求作用域对象:
的Global.asax.cs:
protected void Application_BeginRequest(object sender, EventArgs e)
{
var myObject = SomeMethodThatGetsMyObject();
HttpContext.Current.Items.Add("MyObjectKey", myObject);
}
protected void Application_EndRequest(object sender, EventArgs e)
{
HttpContext.Current.Items.Remove("MyObjectKey");
}
然后在控制器中你可以这样访问:
public ViewResult ThisAction()
{
var myObject = HttpContext.Current.Items["MyObjectKey"] as MyObjectType;
// placing this in view data provides easy access in the view.
ViewData["MyObject"] = myObject;
return View();
}
然后在视图中,您可以从ViewData或直接从HttpContext
访问它<% var myObject = ViewData["MyObject"] as MyObjectType; %>
<!-- If for some reason you don't want it in view data
you can use the HttpContext directly instead -->
<% var myObject = HttpContext.Current.Items["MyObjectKey"] as MyObjectType; %>
其次,会话作用域对象:
此方法将使对象保持在范围内,直到用户的会话结束。
的Global.asax.cs
protected void Session_Start(object sender, EventArgs e)
{
var myObject = SomeMethodThatGetsMyObject();
Session["MyObjectKey"] = myObject;
}
protected void Session_End(object sender, EventArgs e)
{
Session.Remove("MyObjectKey");
}
然后在控制器中你可以这样访问:
public ViewResult ThisAction()
{
var myObject = Session["MyObjectKey"] as MyObjectType;
// placing this in view data provides easy access in the view.
ViewData["MyObject"] = myObject;
return View();
}
然后在视图中,您可以从ViewData或直接从HttpContext
访问它<% var myObject = ViewData["MyObject"] as MyObjectType; %>
<!-- If for some reason you don't want it in view data
you can use the Session directly instead -->
<% var myObject = Session["MyObjectKey"] as MyObjectType; %>
最佳做法
值得一提的是,可以应用一些最佳实践来改进这种设计。首先,不是在视图中传递和使用整个对象,通常最好只将所需的值传递给视图数据,使视图不受赋值和转换代码的影响。 (请记住,如果您要在视图中进行投射,那么您将不得不在视图中处理投射失败的可能性!)
此外,希望拥有一个始终可用的用户范围对象“以防万一”是一种反模式。了解此对象的用途可能有用,以便根据已知的最佳实践建议使用适当的模式来帮助解决问题。
我希望在某个地方我能够帮助一点。
答案 1 :(得分:0)
将它放在控制器的基类中?
老实说,你的设计听起来有些瑕疵......某种“神物”已经进入你的设计。如果你问一个更好的方法来做你正在做的事情,你可能会得到更好的答案......
答案 2 :(得分:0)
听起来你想将一些会话变量传递给你的视图。也许最好的方法是创建一个基本视图模型类,它为您加载会话对象中的这些信息。然后,可以使用此基础对象为每个视图构建定制的视图模型类。
答案 3 :(得分:0)
我同意威尔。将对象粘贴到主控制器派生自的基本控制器类中。
看这里看别人怎么说&gt;&gt; ViewModel-Best-Practices