谁能解释一下,什么时候用

TempData ViewBag ViewData

我有一个要求,我需要在控制器1中设置一个值,控制器将重定向到控制器2,控制器2将呈现视图。

我尝试过使用ViewBag,当我到达控制器2时,值就丢失了。

我能知道什么时候使用和优缺点吗?

谢谢


当前回答

而且viewbag和temptdata的作用域是不同的。Viewbag是基于第一个视图(不是在动作方法之间共享),但是temptdata可以在一个动作方法之间共享。

其他回答

1) TempData

允许您存储重定向时仍能保存的数据。在内部,它使用会话作为备份存储,重定向后,数据被自动清除。模式如下:

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)视图包,视图数据

允许您在控制器动作中存储数据,这些数据将在相应的视图中使用。这假设操作返回一个视图,并且不重定向。仅在当前请求期间存活。

模式如下:

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

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

我的要求是在控制器1中设置一个值 controller将重定向到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。这是因为它内部使用会话,我禁用会话在我的应用程序。我更喜欢用一种更舒适的方式来实现这一点。即:在执行重定向的第一个控制器操作中,将对象存储在数据存储中,并在重定向时使用生成的唯一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);
    }
}

视图保持不变。

TempData

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

查看这个视频

例子

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

如果你注意上面的代码,在TempData被读取之前,RedirectToAction对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

数据将持久化到相应的视图

MVC中的ViewBag, ViewData, TempData和viewstate

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

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

ViewBag和ViewData的相似之处:

当您从控制器移动到视图时,有助于维护数据。用于 将数据从控制器传递到相应的视图。短寿命意味着 值在重定向发生时变为空。这是因为他们的目标 是提供一种在控制器和视图之间通信的方法。这是 服务器调用中的通信机制。

ViewBag和ViewData的区别:

ViewData是派生自的对象字典 viewdatdictionary类,并使用字符串作为键访问。ViewBag 动态属性是否利用了新的动态特性 在c# 4.0。ViewData需要对复杂的数据类型进行类型转换 检查空值以避免错误。ViewBag不需要 复杂数据类型的类型转换。

ViewBag & ViewData示例:

public ActionResult Index()

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

public ActionResult Index()  
{
    ViewData["Name"] = "Arun Prakash";
    return 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);   
}  

而且viewbag和temptdata的作用域是不同的。Viewbag是基于第一个视图(不是在动作方法之间共享),但是temptdata可以在一个动作方法之间共享。

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
    }