【问题标题】:ViewBag, ViewData, TempData, Session - how and when to use them?ViewBag、ViewData、TempData、Session - 如何以及何时使用它们?
【发布时间】:2013-03-04 14:30:37
【问题描述】:

ViewData 和 ViewBag 允许您访问从控制器传递的视图中的任何数据。

这两者之间的主要区别在于您访问数据的方式。 在 ViewBag 中,您使用字符串作为键访问数据 - ViewBag[“numbers”] 在 ViewData 中,您正在使用属性访问数据 - ViewData.numbers。

查看数据示例

控制器

 var Numbers = new List<int> { 1, 2, 3 };

          ViewData["numbers"] = Numbers;

查看

<ul>
 @foreach (var number in (List<int>)ViewData["numbers"])
 {
     <li>@number</li> 
 }

 </ul>

ViewBag示例

控制器

 var Numbers = new List<int> { 1, 2, 3 };

         ViewBag.numbers = Numbers;

查看

<ul>

@foreach (var number in ViewBag.numbers)

{
<li>@number</li> 
}

</ul>

Session 是另一个非常有用的对象,可以保存任何信息。

例如,当用户登录系统时,您希望保持他的授权级别。

// GetUserAuthorizationLevel - some method that returns int value for user authorization level.

Session["AuthorizationLevel"] = GetUserAuthorizationLevel(userID);

只要用户会话处于活动状态,此信息就会存储在会话中。 这可以在 Web.config 文件中更改:

<system.web>
    <sessionState mode="InProc" timeout="30"/>

那么在控制器里面的action:

 public ActionResult LevelAccess()
     {
         if (Session["AuthorizationLevel"].Equals(1))
         {
             return View("Level1");
         }

        if (Session["AuthorizationLevel"].Equals(2))
        {
            return View("Level2");
        }

        return View("AccessDenied");
    }

TempData 与 ViewData 和 ViewBag 非常相似,但是它只包含一个请求的数据。

控制器

// 你创建了一个添加新客户端的方法。

TempData["ClientAdded"] = "Client has been added";

查看

@if (TempData["ClientAdded"] != null)
{ 
   <h3>@TempData["ClientAdded"] </h3>
}

当您想将一些信息从 View 传递到 Controller 时,TempData 很有用。例如,您希望在请求查看时保持时间。

查看

@{
TempData["DateOfViewWasAccessed"] = DateTime.Now;
}

控制器

if (TempData["DateOfViewWasAccessed"] != null)
   {
    DateTime time = DateTime.Parse(TempData["DateOfViewWasAccessed"].ToString()); 
   }

【问题讨论】:

  • 感谢您提供更多信息!这对大多数人来说应该很有帮助。
  • 这里有问题还是这是一篇博文?回答你自己的问题很好,但它应该作为一个答案来完成,而不是作为问题的一部分。更重要的是,这个素材之前已经覆盖过,比如What is the right time for ViewData, ViewBag, Session, TempData
  • 我会记住这一点,并为此感到抱歉。我试着举了更多的例子,也许一些更有经验的开发者也会分享他们的经验。

标签: c# asp.net-mvc visual-studio-2010


【解决方案1】:

ViewBag、ViewData、TempData、Session - 如何以及何时使用它们?

查看包

避免它。尽可能使用视图模型。

原因是当您使用动态属性时不会出现编译错误。很容易意外或故意更改属性名称,然后忘记更新所有用法。

如果您使用 ViewModel,您将不会遇到这个问题。视图模型还将调整 MVC 中的“M”(即业务实体)的责任从控制器和视图转移到了 ViewModel,因此您可以获得具有明确职责的更清晰的代码。

动作

public ActionResult Index()
{
    ViewBag.SomeProperty = "Hello";
    return View();
}

查看(剃刀语法)

@ViewBag.SomeProperty

查看数据

避免它。尽可能使用视图模型。与 ViewBag 的原因相同。

动作

public ActionResult Index()
{
    ViewData["SomeProperty"] = "Hello";
    return View();
}

查看(剃刀语法):

@ViewData["SomeProperty"]

临时数据

您存储在 TempData 中的所有内容都将保留在 tempdata 中,直到您读取它为止,无论其间是否有一个或多个 HTTP 请求。

操作

public ActionResult Index()
{
    TempData["SomeName"] = "Hello";
    return RedirectToAction("Details");
}


public ActionResult Details()
{
    var someName = TempData["SomeName"];
}

【讨论】:

  • “当您需要在多个请求中保留信息时” - 我认为 TempData 只有在被读取之前才是好的。我认为这里使用几个请求有点误导。
  • 我的意思是,无论是两个请求还是中间的 10 个请求,它都会保留在临时数据中,直到您读取它为止。但我明白你的意思,我会详细说明。
  • 谢谢,我经常在我的应用程序中使用 TempData,但我认为它只会保留一个请求,除非您阅读它。所以我们可以说它有点像session,但是数据只能读取一次。
  • 如果您也添加一个解释“会话”的部分会很好。
【解决方案2】:

TempData

意味着是一个非常短暂的实例,你应该只在当前和后续请求期间使用它!由于 TempData 以这种方式工作,您需要确定下一个请求将是什么,并且重定向到另一个视图是您唯一可以保证这一点的时间。因此,使用 TempData 可靠工作的唯一情况是在重定向时。这是因为重定向会终止当前请求(并向客户端发送 HTTP 状态代码 302 Object Moved),然后在服务器上创建一个新请求以提供重定向视图。回顾之前的 HomeController 代码示例意味着 TempData 对象可能会产生与预期不同的结果,因为无法保证下一个请求来源。例如,下一个请求可能来自完全不同的机器和浏览器实例。

查看数据

ViewData 是一个字典对象,您可以将数据放入其中,然后视图可以使用该对象。 ViewData 是 ViewDataDictionary 类的派生类,因此您可以通过熟悉的“键/值”语法进行访问。

查看包

ViewBag 对象是 ViewData 对象的包装器,允许您为 ViewBag 创建动态属性。

public class HomeController : Controller
{
    // ViewBag & ViewData sample
    public ActionResult Index()
    {
        var featuredProduct = new Product
        {
            Name = "Special Cupcake Assortment!",
            Description = "Delectable vanilla and chocolate cupcakes",
            CreationDate = DateTime.Today,
            ExpirationDate = DateTime.Today.AddDays(7),
            ImageName = "cupcakes.jpg",
            Price = 5.99M,
            QtyOnHand = 12
        };

        ViewData["FeaturedProduct"] = featuredProduct;
        ViewBag.Product = featuredProduct;
        TempData["FeaturedProduct"] = featuredProduct;  

        return View();
    }
}

【讨论】:

    【解决方案3】:
    namespace TempData.Controllers
    {
     public class HomeController : Controller
     {
        public ActionResult Index()
        {
            TempData["hello"] = "test"; // still alive
            return RedirectToAction("About");
        }
    
        public ActionResult About()
        {
            //ViewBag.Message = "Your application description page.";
            var sonename = TempData["hello"]; // still alive (second time)
            return RedirectToAction("Contact");
        }
    
    
        public ActionResult Contact()
        {
            var scondtime = TempData["hello"]; // still alive(third time)
            return View();
        }
        public ActionResult afterpagerender()
        {
            var scondtime = TempData["hello"];//now temp data value becomes null
    
            return View();
        }
    }
    

    }

    在上面的对话中,每个人都没有什么困惑。如果您查看我上面的代码,tempdata 就像 viewdata 概念,但它也能够重定向其他视图。这是第一点。

    第二点: 他们中很少有人说它在阅读之前保持价值,而且很少有人会问,所以它会只读时间吗?不是这样。 实际上,您可以在页面渲染之前在一个 postpack 中读取代码中的任意时间。一旦页面渲染发生,如果您再次进行 postpack (request) 意味着,tempdata 值将变为 NULL。

    即使你请求了这么多时间,但临时数据值仍然存在 -->这种情况下你的请求数不应该读取临时数据值。

    【讨论】:

      【解决方案4】:

      简单来说:

      ViewBag 是一个动态(动态:不同程序对同一对象分配多个值的能力)对象,用于将数据从控制器发送到视图。当我们从控制器的动作跳转到某个视图时可以使用它。但是,我们在视图中(在 viewbag 对象中)获得的值不能在其他视图/控制器/js 页面等中进一步复制。含义:控制器->视图(可能)。现在这个值不能发送到下一个视图/控制器。意思是Controller->View->View/controller/some js file(不可能),要携带这个值,你需要定义一些其他变量并将viewbag值存储到其中,然后作为参数发送。

      Tempdata 与 viewbag 有很大不同。它与视图完全无关。当我们将数据从一个动作(方法)发送到同一控制器中的另一个动作时使用它。这就是我们在将临时数据值从一个动作发送到另一个动作时使用 RedirectToAction 的原因。从控制器发送到 veiw 时不会保留 tempdata 的值(因为它不应该这样做)。

      ViewData 与 viewbag 类似,但它是一个字典对象。 ViewData 可能需要类型转换,而 viewbag 可能不需要。这取决于用户他可能想要使用哪一个。

      【讨论】:

        猜你喜欢
        • 2011-12-21
        • 1970-01-01
        • 2012-09-22
        • 1970-01-01
        • 1970-01-01
        • 2013-06-16
        • 1970-01-01
        • 2010-12-02
        相关资源
        最近更新 更多