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

本文关键字:何时使 TempData ViewData Session ViewBag | 更新日期: 2023-09-27 18:02:01

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>

视图包示例

控制器

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

视图

<ul>
@foreach (var number in ViewBag.numbers)
{
<li>@number</li> 
}
</ul>

会话是另一个非常有用的对象,它将保存任何信息。

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

// GetUserAuthorizationLevel - some method that returns int value for user authorization level.
Session["AuthorizationLevel"] = GetUserAuthorizationLevel(userID);

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

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

那么在控制器内部的动作中:

 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>
}

当您想要将某些信息从视图传递到控制器时,TempData 非常有用。例如,您希望在请求查看时保留时间。

视图

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

控制器

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

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

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 以这种方式工作,因此您需要确定下一个请求是什么,并且重定向到另一个视图是唯一可以保证这一点的时间。因此,使用 TempData 可靠工作的唯一情况是重定向时。这是因为重定向会终止当前请求(并将 HTTP 状态代码 302 对象移动到客户端(,然后在服务器上创建新请求以提供重定向视图。回顾前面的 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();
    }
}
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 概念,但它也能够重定向其他视图。 这是第一点。

第二点: 他们中很少有人说它在阅读之前保持价值,很少有人问它会只读取时间吗?并非如此。实际上,在页面呈现之前,您可以在一个后期包中读取代码中的任意时间。页面呈现发生后,如果再次进行后期打包(请求(意味着,则 tempdata 值将变为 NULL。

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

简单来说:

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

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

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