如何在控制器和视图页面之间共享对象?

时间:2009-08-22 21:36:05

标签: c# asp.net asp.net-mvc

目前我正在覆盖ASP.NET ViewPage的OnLoad事件。这样就可以与所有视图共享一个对象。但我现在需要能够在控制器中访问该对象;最好的方法是什么?

基本上,我想与视图页面和控制器共享一个对象(对于Web应用程序的每个用户来说都是唯一的......所以单例出来了)。

谢谢!

4 个答案:

答案 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