C# ViewBag、ViewData、TempData、Session - 如何以及何时使用它们?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15203870/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ViewBag, ViewData, TempData, Session - how and when to use them?
提问by Adam Bielecki
ViewData and ViewBag allows you to access any data in view that was passed from controller.
ViewData 和 ViewBag 允许您访问从控制器传递的视图中的任何数据。
The main difference between those two is the way you are accessing the data. In ViewBag you are accessing data using string as keys - ViewBag[“numbers”] In ViewData you are accessing data using properties - ViewData.numbers.
这两者之间的主要区别在于您访问数据的方式。在 ViewBag 中,您使用字符串作为键访问数据 - ViewBag[“numbers”] 在 ViewData 中,您使用属性访问数据 - ViewData.numbers。
ViewDataexample
视图数据示例
CONTROLLER
控制器
var Numbers = new List<int> { 1, 2, 3 };
ViewData["numbers"] = Numbers;
VIEW
看法
<ul>
@foreach (var number in (List<int>)ViewData["numbers"])
{
<li>@number</li>
}
</ul>
ViewBagexample
ViewBag示例
CONTROLLER
控制器
var Numbers = new List<int> { 1, 2, 3 };
ViewBag.numbers = Numbers;
VIEW
看法
<ul>
@foreach (var number in ViewBag.numbers)
{
<li>@number</li>
}
</ul>
Sessionis another very useful object that will hold any information.
Session是另一个非常有用的对象,可以保存任何信息。
For instance when user logged in to the system you want to hold his authorization level.
例如,当用户登录系统时,您希望保持其授权级别。
// GetUserAuthorizationLevel - some method that returns int value for user authorization level.
Session["AuthorizationLevel"] = GetUserAuthorizationLevel(userID);
This information will be stored in Session as long as user session is active. This can be changed in Web.config file:
只要用户会话处于活动状态,此信息就会存储在会话中。这可以在 Web.config 文件中更改:
<system.web>
<sessionState mode="InProc" timeout="30"/>
So then in controller inside the action :
那么在控制器里面的动作:
public ActionResult LevelAccess()
{
if (Session["AuthorizationLevel"].Equals(1))
{
return View("Level1");
}
if (Session["AuthorizationLevel"].Equals(2))
{
return View("Level2");
}
return View("AccessDenied");
}
TempDatais very similar to ViewData and ViewBag however it will contain data only for one request.
TempData与 ViewData 和 ViewBag 非常相似,但是它只包含一个请求的数据。
CONTROLLER
控制器
// You created a method to add new client.
// 您创建了一个方法来添加新客户端。
TempData["ClientAdded"] = "Client has been added";
VIEW
看法
@if (TempData["ClientAdded"] != null)
{
<h3>@TempData["ClientAdded"] </h3>
}
TempData is useful when you want to pass some information from View to Controller. For instance you want to hold time when view was requested.
当您想将一些信息从 View 传递到 Controller 时,TempData 很有用。例如,您希望在请求查看时保留时间。
VIEW
看法
@{
TempData["DateOfViewWasAccessed"] = DateTime.Now;
}
CONTROLLER
控制器
if (TempData["DateOfViewWasAccessed"] != null)
{
DateTime time = DateTime.Parse(TempData["DateOfViewWasAccessed"].ToString());
}
采纳答案by jgauffin
ViewBag, ViewData, TempData, Session - how and when to use them?
ViewBag、ViewData、TempData、Session - 如何以及何时使用它们?
ViewBag
查看包
Avoid it. Use a view model when you can.
躲开它。尽可能使用视图模型。
The reason is that when you use dynamic properties you will not get compilation errors. It's really easy to change a property name by accident or by purpose and then forget to update all usages.
原因是当您使用动态属性时,您不会遇到编译错误。意外或故意更改属性名称然后忘记更新所有用法真的很容易。
If you use a ViewModel you won't have that problem. A view model also moves the responsibility of adapting the "M" (i.e. business entities) in MVC from the controller and the view to the ViewModel, thus you get cleaner code with clear responsibilities.
如果你使用 ViewModel 你就不会有这个问题。视图模型还将调整 MVC 中的“M”(即业务实体)的责任从控制器和视图转移到 ViewModel,因此您可以获得更清晰的代码和明确的责任。
Action
行动
public ActionResult Index()
{
ViewBag.SomeProperty = "Hello";
return View();
}
View (razor syntax)
视图(剃刀语法)
@ViewBag.SomeProperty
ViewData
查看数据
Avoit it. Use a view model when you can. Same reason as for ViewBag.
避免它。尽可能使用视图模型。与 ViewBag 的原因相同。
Action
行动
public ActionResult Index()
{
ViewData["SomeProperty"] = "Hello";
return View();
}
View (razor syntax):
查看(剃刀语法):
@ViewData["SomeProperty"]
Temp data
临时数据
Everything that you store in TempData
will stay in tempdata until you read it, no matter if there are one or several HTTP requests in between.
您存储的所有内容都TempData
将保留在临时数据中,直到您读取它为止,无论中间是一个还是多个 HTTP 请求。
Actions
行动
public ActionResult Index()
{
TempData["SomeName"] = "Hello";
return RedirectToAction("Details");
}
public ActionResult Details()
{
var someName = TempData["SomeName"];
}
回答by Adam Bielecki
is meant to be a very short-lived instance, and you should only use it during the current and the subsequent requests only! Since TempData works this way, you need to know for sure what the next request will be, and redirecting to another view is the only time you can guarantee this. Therefore, the only scenario where using TempData will reliably work is when you are redirecting. This is because a redirect kills the current request (and sends HTTP status code 302 Object Moved to the client), then creates a new request on the server to serve the redirected view. Looking back at the previous HomeController code sample means that the TempData object could yield results differently than expected because the next request origin can't be guaranteed. For example, the next request can originate from a completely different machine and browser instance.
是一个非常短暂的实例,您应该只在当前和后续请求中使用它!由于 TempData 以这种方式工作,您需要确定下一个请求将是什么,并且重定向到另一个视图是唯一可以保证这一点的时间。因此,使用 TempData 可靠工作的唯一情况是在您重定向时。这是因为重定向会终止当前请求(并将 HTTP 状态代码 302 Object Moved 发送到客户端),然后在服务器上创建一个新请求来为重定向视图提供服务。回顾之前的 HomeController 代码示例意味着 TempData 对象可能产生与预期不同的结果,因为无法保证下一个请求来源。例如,下一个请求可能来自完全不同的机器和浏览器实例。
ViewData
查看数据
ViewData is a dictionary object that you put data into, which then becomes available to the view. ViewData is a derivative of the ViewDataDictionary class, so you can access by the familiar "key/value" syntax.
ViewData 是一个字典对象,您将数据放入其中,然后该对象可用于视图。ViewData 是 ViewDataDictionary 类的派生类,因此您可以通过熟悉的“键/值”语法进行访问。
ViewBag
查看包
The ViewBag object is a wrapper around the ViewData object that allows you to create dynamic properties for the 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();
}
}
回答by user3234419
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();
}
}
}
}
In above conversation, there is little confuse for everyone. if you look at my above code, tempdata is like viewdata concept but then it is able to redirect other view also. this is first point.
在上面的对话中,每个人都没有什么困惑。如果您查看我上面的代码,tempdata 就像 viewdata 概念,但它也能够重定向其他视图。这是第一点。
second point: few of them are saying it maintains value till read and few of them are asking that so will it read only time? not so. Actually, you can read any number of time inside your code in one postpack before page render. once page render happened, if you do again postpack (request) means, the tempdata value becomes NULL.
第二点:很少有人说它在读取前保持价值,也很少有人问它是否只读取时间?不是这样。实际上,在页面渲染之前,您可以在一个 postpack 中读取任意次数的代码。一旦页面渲染发生,如果你再次执行 postpack(请求)手段,tempdata 值变为 NULL。
even you are requesting so many time , but the tempdata value is still alive -->this case your number of request should not read temp data value.
即使您请求了这么多时间,但 tempdata 值仍然存在 --> 在这种情况下,您的请求数不应读取临时数据值。
回答by Bhawishya
In simple terms:
简单来说:
ViewBag is a dynamic (dynamic: ability to assign more than one value by different programs on the same object) object which is used to send data from controller to view. It can be used when we jump from controller's action to some view. However the value which we get in the view(in the viewbag object) can not be further replicated in other view/controller/js page etc. Meaning: Controller->View (possible). Now this value can not be send to next view/controller. Meaning Controller->View->View/controller/some js file (not possible), to carry this value you need to define some other variable and store viewbag value into it and then send it as a parameter.
ViewBag 是一种动态(动态:能够通过不同程序对同一对象分配多个值的能力)对象,用于将数据从控制器发送到视图。当我们从控制器的动作跳转到某个视图时可以使用它。然而,我们在视图中(在视图包对象中)获得的值不能在其他视图/控制器/js 页面等中进一步复制。含义:控制器->视图(可能)。现在这个值不能发送到下一个视图/控制器。含义 Controller->View->View/controller/some js file (not possible),要携带这个值你需要定义一些其他的变量并将viewbag值存储到其中,然后将其作为参数发送。
Tempdata is very much different than viewbag. It has nothing to do with view at all. It is used when we send data from one action(method) to other action in the same controller. That's the reason we use RedirectToAction whenever sending tempdata value from one action to another. Value of tempdata are not retained when send from controller to veiw (because it is not meant to do so).
Tempdata 与 viewbag 有很大不同。它与视图完全没有关系。当我们将数据从一个动作(方法)发送到同一控制器中的另一个动作时使用。这就是我们在将临时数据值从一个操作发送到另一个操作时使用 RedirectToAction 的原因。从控制器发送到 veiw 时不保留 tempdata 的值(因为它不是故意这样做的)。
ViewData is simillar to viewbag but is a dictionary object. ViewData may require type casting while viewbag may not. It depends on the user which one he may want to use.
ViewData 类似于 viewbag 但它是一个字典对象。ViewData 可能需要类型转换,而 viewbag 可能不需要。这取决于用户可能想要使用哪一种。