ViewBag,ViewData和TempData

时间:2011-11-03 10:22:38

标签: asp.net-mvc-3

任何机构都可以解释,何时使用

  1. TempData的
  2. ViewBag
  3. 的ViewData
  4. 我有一个要求,我需要在控制器中设置一个值,控制器将重定向到控制器二,控制器二将呈现视图。

    我尝试使用ViewBag,当我到达Controller Two时,该值会丢失。

    我可以知道何时使用和优缺点?

    由于

7 个答案:

答案 0 :(得分:287)

  

1)TempData

允许您存储为重定向而存活的数据。在内部,它使用Session作为后备存储,在重定向之后,数据被自动驱逐。模式如下:

public ActionResult Foo()
{
    // store something into the tempdata that will be available during a single redirect
    TempData["foo"] = "bar";

    // you should always redirect if you store something into TempData to
    // a controller action that will consume this data
    return RedirectToAction("bar");
}

public ActionResult Bar()
{
    var foo = TempData["foo"];
    ...
}
  

2)ViewBag,ViewData

允许您将数据存储在将在相应视图中使用的控制器操作中。这假定操作返回视图但不重定向。仅在当前请求期间生活。

模式如下:

public ActionResult Foo()
{
    ViewBag.Foo = "bar";
    return View();
}

并在视图中:

@ViewBag.Foo

或使用ViewData:

public ActionResult Foo()
{
    ViewData["Foo"] = "bar";
    return View();
}

并在视图中:

@ViewData["Foo"]

ViewBag只是ViewData的动态包装器,仅存在于ASP.NET MVC 3中。

这就是说,这两种结构都不应该被使用。您应该使用视图模型和强类型视图。所以正确的模式如下:

查看型号:

public class MyViewModel
{
    public string Foo { get; set; }
}

动作:

public Action Foo()
{
    var model = new MyViewModel { Foo = "bar" };
    return View(model);
}

强类型视图:

@model MyViewModel
@Model.Foo

在简短的介绍之后,让我们回答你的问题:

  

我的要求是我想在控制器中设置一个值,即   控制器将重定向到ControllerTwo,Controller2将呈现   观点。

public class OneController: Controller
{
    public ActionResult Index()
    {
        TempData["foo"] = "bar";
        return RedirectToAction("index", "two");
    }
}

public class TwoController: Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            Foo = TempData["foo"] as string
        };
        return View(model);
    }
}

和相应的视图(~/Views/Two/Index.cshtml):

@model MyViewModel
@Html.DisplayFor(x => x.Foo)

使用TempData也有一些缺点:如果用户在目标页面上点击F5,数据将会丢失。

我个人也不使用TempData。这是因为在内部它使用Session我在我的应用程序中禁用会话。我更喜欢一种更加RESTful的方式来实现这一目标。这是:在第一个执行重定向的控制器操作中,将对象存储在数据存储中,并在重定向时使用生成的唯一ID。然后在目标操作上使用此id来获取最初存储的对象:

public class OneController: Controller
{
    public ActionResult Index()
    {
        var id = Repository.SaveData("foo");
        return RedirectToAction("index", "two", new { id = id });
    }
}

public class TwoController: Controller
{
    public ActionResult Index(string id)
    {
        var model = new MyViewModel
        {
            Foo = Repository.GetData(id)
        };
        return View(model);
    }
}

视图保持不变。

答案 1 :(得分:15)

ASP.NET MVC为我们提供了三个选项ViewData,ViewBag和TempData,用于将数据从控制器传递到视图和下一个请求。 ViewData和ViewBag几乎相似,TempData承担额外的责任。让我们讨论或获得这三个对象的关键点:

ViewBag&的相似之处ViewData:

  • 帮助您在从控制器移动到视图时保持数据。
  • 用于将数据从控制器传递到相应的视图。
  • 短寿命意味着重定向发生时,值变为空。这是 因为他们的目标是提供一种沟通方式 控制器和视图。它是一种沟通机制 服务器电话。

ViewBag与&之间的区别ViewData的:

  • ViewData是派生自的对象的字典 ViewDataDictionary类,可以使用字符串作为键进行访问。
  • ViewBag是一个利用新动态的动态属性 C#4.0中的功能。
  • ViewData需要对复杂数据类型进行类型转换并检查 空值以避免错误。
  • ViewBag不需要对复杂数据类型进行类型转换。

ViewBag& ViewData示例:

public ActionResult Index()
{
    ViewBag.Name = "Monjurul Habib";
    return View();
}


public ActionResult Index()
{
    ViewData["Name"] = "Monjurul Habib";
    return View();
} 

在视图中:

@ViewBag.Name 
@ViewData["Name"] 

<强> TempData的:

TempData也是一个派生自TempDataDictionary类的字典,存储在短生命会话中,它是一个字符串键和对象值。不同之处在于物体的生命周期。 TempData保存HTTP请求时间的信息。这仅意味着从一个页面到另一个页面。这也适用于302/303重定向,因为它位于相同的HTTP请求中。当您从一个控制器移动到另一个控制器或从一个操作移动到其他操作时,有助于维护数据。换句话说,当您重定向时,“TempData”有助于维护这些重定向之间的数据。它在内部使用会话变量。在当前和后续请求期间使用临时数据仅意味着在您确定下一个请求将重定向到下一个视图时使用它。它需要对复杂数据类型进行类型转换,并检查空值以避免错误。通常用于存储一次消息,如错误消息,验证消息。

public ActionResult Index()
{
  var model = new Review()
            {
                Body = "Start",
                Rating=5
            };
    TempData["ModelName"] = model;
    return RedirectToAction("About");
}

public ActionResult About()
{
    var model= TempData["ModelName"];
    return View(model);
}

最后一种机制是Session,它像ViewData一样工作,就像一个字典,它接受键的字符串和值的对象。这个存储在客户端Cookie中,可以使用更长时间。它还需要更多验证才能永远不会有任何机密信息。关于ViewData或ViewBag,您应该智能地使用它来提高应用程序性能。因为每个动作都经历了常规asp.net mvc请求的整个生命周期。您可以在子操作中使用ViewData / ViewBag,但请注意不要使用它来填充可能污染控制器的无关数据。

答案 2 :(得分:11)

TempData的

基本上它就像一个DataReader,一旦读取,数据就会丢失。

Check this Video

示例

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
        TempData["T"] = "T";
        return RedirectToAction("About");
    }

    public ActionResult About()
    {
        return RedirectToAction("Test1");
    }

    public ActionResult Test1()
    {
        String str = TempData["T"]; //Output - T
        return View();
    }
}

如果您注意上面的代码,RedirectToAction对TempData没有影响,直到读取TempData。因此,一旦读取了TempData,值就会丢失。

如何在阅读后保留TempData?

检查操作方法测试1和测试2

中的输出
public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
        TempData["T"] = "T";
        return RedirectToAction("About");
    }

    public ActionResult About()
    {
        return RedirectToAction("Test1");
    }

    public ActionResult Test1()
    {
        string Str = Convert.ToString(TempData["T"]);
        TempData.Keep(); // Keep TempData
        return RedirectToAction("Test2");
    }

    public ActionResult Test2()
    {
        string Str = Convert.ToString(TempData["T"]); //OutPut - T
        return View();
    }
}

如果您注意上面的代码,RedirectToAction之后以及读取数据之后数据不会丢失,原因是,我们正在使用TempData.Keep()。就是那个

通过这种方式,您可以在其他控制器中保持持久性。

ViewBag / ViewData的

数据将保留到相应的视图

答案 3 :(得分:4)

Asp.Net中的TempData MVC是非常有用的功能之一。它用于将数据从当前请求传递到后续请求。换句话说,如果我们想在重定向发生时将数据从一个页面发送到另一个页面,我们可以使用TempData,但我们需要在代码中做一些考虑以在MVC中实现此功能。因为TempData的寿命非常短,并且仅在目标视图完全加载之前存在。但是,我们可以使用Keep()方法在TempData中保存数据。

Read More

答案 4 :(得分:3)

MVC中的ViewBag,ViewData,TempData和View状态

http://royalarun.blogspot.in/2013/08/viewbag-viewdata-tempdata-and-view.html

ASP.NET MVC为我们提供了三个选项ViewData,VieBag和TempData,用于将数据从控制器传递到视图和下一个请求。 ViewData和ViewBag几乎相似,TempData承担额外的责任。

ViewBag&amp;的相似之处ViewData:

  

帮助您在从控制器移动到视图时保持数据。习惯了   将数据从控制器传递到相应的视图。寿命短意味着   重定向发生时,value变为null。这是因为他们的目标   是提供一种在控制器和视图之间进行通信的方法。它的   服务器调用中的通信机制。

ViewBag与&之间的区别ViewData的:

  

ViewData是派生自的对象的字典   ViewDataDictionary类,可以使用字符串作为键访问。 ViewBag   是一个动态属性,利用新的动态功能   在C#4.0中。 ViewData需要对复杂数据类型进行类型转换   检查空值以避免错误。 ViewBag不需要   对复杂数据类型进行类型转换。

ViewBag&amp; ViewData示例:

public ActionResult Index()

{  
    ViewBag.Name = "Arun Prakash";
    return View();    
}

public ActionResult Index()  
{
    ViewData["Name"] = "Arun Prakash";
    return View(); 
}

在View中,我们称之为:

@ViewBag.Name   
@ViewData["Name"]

<强> TempData的:

  

帮助您从一个控制器移动到另一个控制器时保持数据   控制器或从一个动作到其他动作。换句话说,当你   重定向,“Tempdata”有助于维护这些重定向之间的数据。   它在内部使用会话变量。 TempData意味着非常好   短期实例,你应该只在当前使用它   以及后续的请求

使用TempData可靠地工作的唯一方案是重定向时。这是因为重定向会终止当前请求(并将HTTP状态代码302 Object Moved发送到客户端),然后在服务器上创建新请求以提供重定向视图。

它需要对复杂数据类型进行类型转换,并检查空值以避免错误。

public ActionResult Index()
{   
   var model = new Review()  
   {  
      Body = "Start",  
      Rating=5  
   };  

    TempData["ModelName"] = model;    
    return RedirectToAction("About");   
} 

public ActionResult About()       
{  
    var model= TempData["ModelName"];  
    return View(model);   
}  

答案 5 :(得分:1)

void Keep()

Calling this method with in the current action ensures that all the items in TempData are not removed at the end of the current request.

    @model MyProject.Models.EmpModel;
    @{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "About";
    var tempDataEmployeet = TempData["emp"] as Employee; //need typcasting
    TempData.Keep(); // retains all strings values
    } 

void Keep(string key)

Calling this method with in the current action ensures that specific item in TempData is not removed at the end of the current request.

    @model MyProject.Models.EmpModel;
    @{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "About";
    var tempDataEmployeet = TempData["emp"] as Employee; //need typcasting
    TempData.Keep("emp"); // retains only "emp" string values
    } 

答案 6 :(得分:1)

的TempData 将在第一次阅读之前一直可用,一旦你阅读它就不再可用了将快速消息也传递到第一次阅读后将会消失的视图。 ViewBag 将快速数据传递给视图时更有用,通常你应该通过模型将所有数据传递给视图,但是有些情况下你直接从类映射到类似于实体框架的数据库 在这种情况下,你不需要改变你的模型以传递新的数据,你可以将其粘贴到viewbag中 ViewData只是ViewBag的索引版本,在MVC3之前使用