16

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);

只要用户会话处于活动状态,此信息就会存储在 Session 中。这可以在 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>
}

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

看法

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

控制器

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

4 回答 4

17

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"];
}
于 2013-03-04T14:41:28.753 回答
3

临时数据

意味着是一个非常短暂的实例,您应该只在当前和后续请求期间使用它!由于 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();
    }
}
于 2013-03-04T14:35:38.850 回答
0
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。

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

于 2015-08-20T10:02:52.370 回答
0

简单来说:

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

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

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

于 2018-04-16T07:20:14.107 回答