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

时间:2013-03-04 14:30:37

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

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

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

ViewData 示例

CONTROLLER

 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 示例

CONTROLLER

 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非常相似,但它只包含一个请求的数据。

CONTROLLER

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

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

查看

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

当您想要将某些信息从View传递给Controller时,TempData非常有用。例如,您希望在请求查看时保留时间。

查看

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

CONTROLLER

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

4 个答案:

答案 0 :(得分:17)

  

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

ViewBag

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

原因是当您使用动态属性时,您将不会遇到编译错误。通过意外或目的更改属性名称非常容易,然后忘记更新所有用法。

如果您使用ViewModel,则不会出现此问题。视图模型还负责将MVC中的“M”(即业务实体)从控制器和视图调整到ViewModel,从而获得更清晰的代码并具有明确的职责。

<强>动作

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

查看(剃刀语法)

@ViewBag.SomeProperty

的ViewData

避免它。尽可能使用视图模型。与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"];
}

答案 1 :(得分:3)

  

TempData

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

  

的ViewData

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

  

ViewBag

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

答案 2 :(得分: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值仍然存在 - &gt;这种情况下您的请求数量不应该读取临时数据值。

答案 3 :(得分:0)

简单来说:

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

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

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