ChatGPT解决这个技术问题 Extra ChatGPT

ViewBag、ViewData 和 TempData

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

TempData ViewBag ViewData

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

我曾尝试使用 ViewBag,但当我到达控制器 2 时,该值会丢失。

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

谢谢

This 是一篇很好的文章,它解释了这些差异。
stackoverflow.com/a/17199709/2015869

I
IEnjoyEatingVegetables

1)临时数据

允许您存储将在重定向后仍然存在的数据。在内部,它使用 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);
    }
}

视图保持不变。


很好的答案,但我不同意教条式的说法“这两种结构都不应该被使用”。我发现了 ViewBag 的一些合法用途。例如,我在我的所有视图上设置了一个 ViewBag.Title 属性,该属性在我的 _Layout.cshtml 基本视图文件中使用。我使用它的另一种情况是向用户提供信息消息(例如“产品保存成功!”)。我在 Layout.cshtml 中放置了一些通用标记以呈现消息(如果提供),这允许我在任何操作中设置 ViewBag.Message。在这两种情况下使用 ViewModel 属性都有很多缺点。
我不得不同意 Jesse 的观点,虽然这是一个很好的描述,但公然说没有充分的理由使用 ViewBag 只是一个见仁见智的问题,而不是事实上的问题。过度使用 ViewBag 肯定是一种不好的做法,一些开发人员陷入了这个陷阱,但有品位地使用它是一种强大的资源。
@ron.defreitas,好吧,然后告诉我你为什么要使用 ViewBag 的一个很好的理由。当 ViewBag 有一些用途时,请描述一个特定的真实世界场景。既然你说它是,我引用强大的资源,我猜你有一些特定的情况,这个强大的资源强大的。由于我在职业生涯中从未使用过它,我很高兴了解人们如何使用这种强大的武器。
我们这里有一个精英。 Darin, Jesse 特别提到了一个这样的例子。仅仅因为总是有其他的做事方式并不会自动否定它们的用处。
@DarinDimitrov:我现在有一个场景,我需要从属性方法中将一些信息传递给视图。使用 filterContext.Controller.ViewData 比尝试将其传递给强类型视图要容易得多。就是说,谢谢您的解释,这非常有用。
佚名

临时数据

基本上它就像一个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?

检查 Action Method Test 1 和 Test 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

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


E
Er. ßridy

MVC 中的 ViewBag、ViewData、TempData 和视图状态

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 是从 ViewDataDictionary 类派生的对象字典,可使用字符串作为键进行访问。 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(); 
}

在 View 中,我们调用如下:

@ViewBag.Name   
@ViewData["Name"]

临时数据:

当您从一个控制器移动到另一个控制器或从一个操作移动到另一个操作时,有助于维护数据。换句话说,当您重定向时,“临时数据”有助于维护这些重定向之间的数据。它在内部使用会话变量。 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);   
}  

S
Saineshwar Bageri - MVP
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
    } 

D
David Fawzy

TempData 在第一次阅读之前始终可用,一旦你阅读它,它就不再可用了,它可以用于传递快速消息以查看第一次阅读后将消失的信息。 ViewBag 在将数据快速传递给视图时它更有用,通常您应该通过模型将所有数据传递给视图,但是在某些情况下,您的模型直接来自映射到数据库之类的实体框架的类,在这种情况下您不需要't what to change you model to pass a new piece, you can stick that into the viewbag ViewData is just indexed version of ViewBag and was used before MVC3


E
Elnaz

viewbag 和 temptdata 的范围也不同。 viewbag 基于第一个视图(不在动作方法之间共享),但 temptdata 可以在动作方法和彼此之间共享。