asp.net-mvc MVC ViewBag 最佳实践
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11262034/
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
MVC ViewBag Best Practice
提问by Nate Pet
For the ViewBag, I heard it was a no-no to use. I would assume have the content from the ViewBag should be incorporated into a view model?
对于 ViewBag,我听说它不能使用。我认为应该将 ViewBag 中的内容合并到视图模型中吗?
Question:
题:
Is my assumption above the best practice. (Not to use a ViewBag and second to have it in the view model)
Are there situations where a ViewBag is absolutely necessary?
我的假设是否高于最佳实践。(不要使用 ViewBag,然后在视图模型中使用它)
是否存在绝对需要 ViewBag 的情况?
采纳答案by Shyju
ViewBag is a dynamic dictionary. So when using ViewBag to transfer data between action methods and views, your compiler won't be able to catch if you make a typo in your code when trying to access the ViewBag item in your view. Your view will crash at run time :(
ViewBag 是一个动态字典。因此,当使用 ViewBag 在操作方法和视图之间传输数据时,如果您在尝试访问视图中的 ViewBag 项时在代码中输入错误,则编译器将无法捕获。您的视图将在运行时崩溃 :(
Generally it is a good idea to use a view model to transfer data between your action methods and views. view model is a simple POCO class which has properties specific to the view. So if you want to pass some additional data to view, Add a new property to your view model and use that.Strongly typed Views make the code cleaner and more easy to maintain. With this approach, you don't need to do explicit casting of your viewbag dictionary item to some types back and forth which you have to do with view bag.
通常,使用视图模型在操作方法和视图之间传输数据是个好主意。视图模型是一个简单的 POCO 类,它具有特定于视图的属性。因此,如果您想传递一些额外的数据来查看,请向您的视图模型添加一个新属性并使用它。强类型视图使代码更清晰,更易于维护。使用这种方法,您不需要将 viewbag 字典项显式转换为某些类型,而这与 view bag 相关。
public class ProductsForCategoryVm
{
public string CategoryName { set;get; }
public List<ProductVm> Products { set;get;}
}
public class ProductVm
{
public int Id {set;get;}
public string Name { set;get;}
}
And in your action method, create an object of this view model, load the properties and send that to the view.
在您的操作方法中,创建此视图模型的对象,加载属性并将其发送到视图。
public ActionResult Category(int id)
{
var vm= new ProductsForCategoryVm();
vm.CategoryName = "Books";
vm.Products= new List<ProductVm> {
new ProductVm { Id=1, Name="The Pragmatic Programmer" },
new ProductVm { Id=2, Name="Clean Code" }
}
return View(vm);
}
And your view, which is strongly typed to the view model,
你的视图是强类型的视图模型,
@model ProductsForCategoryVm
<h2>@Model.CategoryName</h2>
@foreach(var item in Model.Products)
{
<p>@item.Name</p>
}
Dropdown data ?
下拉数据 ?
A lot of tutorials/books has code samples which uses ViewBag for dropdown data. I personally still feel that ViewBag's should not be used for this. It should be a property of type List<SelectListItem> in your view model to pass the dropdown data. Here is a postwith example code on how to do that.
许多教程/书籍都有使用 ViewBag 作为下拉数据的代码示例。我个人还是觉得 ViewBag 不应该用于这个。它应该是List<SelectListItem视图模型中 >类型的属性来传递下拉数据。这是一篇关于如何做到这一点的示例代码的帖子。
Are there situations where a ViewBag is absolutely necessary?
是否存在绝对需要 ViewBag 的情况?
There are some valid use cases where you can(not necessary) use ViewBag to send data. For example, you want to display something on your Layout page, you can use ViewBag for that. Another example is ViewBag.Title(for the page title) present in the default MVC template.
有一些有效的用例,您可以(不是必需)使用 ViewBag 发送数据。例如,你想在你的布局页面上显示一些东西,你可以使用 ViewBag。另一个示例是ViewBag.Title(对于页面标题)存在于默认 MVC 模板中。
public ActionResult Create()
{
ViewBag.AnnouncementForEditors="Be careful";
return View();
}
And in the layout, you can read the ViewBag.AnnouncementForEditors
在布局中,您可以阅读 ViewBag.AnnouncementForEditors
<body>
<h1>@ViewBag.AnnouncementForEditors</h1>
<div class="container body-content">
@RenderBody()
</div>
</body>
回答by SadullahCeran
1) Is my assumption above the best practice. (Not to use a ViewBag and second to have it in the view model)
1)我的假设是否高于最佳实践。(不要使用 ViewBag,然后在视图模型中使用它)
You should use viewmodels instead of passing data via ViewBag as much as possible.
您应该尽可能使用视图模型而不是通过 ViewBag 传递数据。
2) Are there situations where a ViewBag is absolutely necessary?
2) 是否存在绝对需要 ViewBag 的情况?
There is no situation where a ViewBag is absolutely necessary. However, there are some data I personally prefer using ViewBag instead of View Model. For example, when I need to populate a dropdown box for predefined values (i.e Cities), I use ViewBag for carrying SelectListItem array to view. I prefer not to pollute my ViewModels with this data.
没有任何情况下 ViewBag 是绝对必要的。但是,有一些数据我个人更喜欢使用 ViewBag 而不是 View Model。例如,当我需要为预定义值(即城市)填充下拉框时,我使用ViewBag 携带SelectListItem 数组进行查看。我不想用这些数据污染我的 ViewModel。
回答by Chris S
The issue with ViewBags and the recommended best practice boils down to compile time checking. ViewBags are just dictionaries and with that you get 'magic' strings, so if you end up changing the object type of one of the viewbag items or the key name you won't know until runtime, even if you precompile the views using <MvcBuildViews>true</MvcBuildViews>.
ViewBags 的问题和推荐的最佳实践归结为编译时间检查。ViewBags 只是字典,因此您会得到“魔法”字符串,因此,如果您最终更改了 viewbag 项目之一的对象类型或键名,您直到运行时才会知道,即使您使用<MvcBuildViews>true</MvcBuildViews>.
Sticking to view models is best, even if you have to alter them to fit a specific view now and again.
坚持使用视图模型是最好的,即使您必须不时更改它们以适应特定视图。
回答by Darin Dimitrov
1) Is my assumption above the best practice. (Not to use a ViewBag and second to have it in the view model)
1)我的假设是否高于最佳实践。(不要使用 ViewBag,然后在视图模型中使用它)
Yes.
是的。
2) Are there situations where a ViewBag is absolutely necessary?
2) 是否存在绝对需要 ViewBag 的情况?
No. Everything that you have stored in a ViewBag could go into the view model passed to the view.
不。您存储在 ViewBag 中的所有内容都可以进入传递给视图的视图模型。
回答by Erick T
I have found some use for ViewBag where there is common functionality across all pages, and the functionality does not depend on the page being shown. For example, say you are building StackOverflow. The job board appears on each page, but the jobs shown have nothing to do with the page (my usage was similar in concept). Adding a property to each ViewModel would be difficult and time consuming, and a lotof fluff to your tests. I don't think it is worth it in this situation.
我发现 ViewBag 有一些用途,其中所有页面都有通用功能,并且该功能不依赖于显示的页面。例如,假设您正在构建 StackOverflow。工作板出现在每个页面上,但显示的工作与页面无关(我的用法在概念上相似)。为每个 ViewModel 添加一个属性既困难又耗时,并且会给您的测试带来很多麻烦。我认为在这种情况下不值得。
I have used a base ViewModel class with the cross cutting data, but if you more than one (e.g., jobs & list of stack exchange sites), you either have to start stuffing extra data in, or some other abuse of a ViewModel, plus you need a ViewModel builder to populate the base data.
我使用了一个带有横切数据的基本 ViewModel 类,但是如果您有多个(例如,工作和堆栈交换站点列表),您要么必须开始填充额外的数据,或者对 ViewModel 进行一些其他滥用,加上您需要一个 ViewModel 构建器来填充基本数据。
As for the magic strings problem, there are a lot of solutions. Constants, extension methods, etc.
至于魔弦问题,有很多解决方法。常量、扩展方法等。
With all that said, if you have something that is displayed on your page that depends on the context of the page, a ViewModel is your friend.
尽管如此,如果您的页面上显示的内容取决于页面的上下文,那么 ViewModel 就是您的朋友。
Erick
埃里克
回答by Developer
If you cannot re-design EXISTING ViewModel use ViewBag.
如果您无法重新设计 EXISTING ViewModel,请使用 ViewBag。
回答by Tohid
- No. Use ViewModels.
- No. If you design a perfect ViewModel, you never need a ViewBag.
- 不。使用ViewModels。
- 不。如果你设计了一个完美的 ViewModel,你永远不需要 ViewBag。
回答by Dinh Tran
2.Are there situations where a ViewBag is absolutely necessary?
2.是否存在绝对需要 ViewBag 的情况?
In some case you'll need to share your data from the Controller across the layouts, views and partial views. In this case, ViewBag is very helpful and I doubt there's any better way.
在某些情况下,您需要跨布局、视图和部分视图共享来自控制器的数据。在这种情况下,ViewBag 非常有用,我怀疑有没有更好的方法。
回答by Xeevis
If there were no use cases for it, it wouldn't be implemented in the first place. Yes you can do everything with ViewModels, but what if you don't really need one? One such scenario is editing entities. You can pass DTO directly as a model.
如果没有用例,它就不会首先实现。是的,你可以用 ViewModels 做任何事情,但如果你真的不需要一个怎么办?一种这样的场景是编辑实体。您可以直接将 DTO 作为模型传递。
@model CategoryDto
<div class="md-form form-sm">
<input asp-for="Name" class="form-control">
<label asp-for="Name">("Category Name")</label>
</div>
But what if you want to select Category parent? Entity DTO ideally holds only it's own values, so to populate select list you use ViewBag
但是如果你想选择 Category parent 怎么办?实体 DTO 理想情况下只保存它自己的值,因此要填充选择列表,请使用 ViewBag
<select asp-for="ParentId" asp-items="ViewBag.ParentList">
<option value="">None</option>
</select>
Why do this? Well if you have 50 types of entities each with some sort of select from different values, you just avoided creating 50 extra ViewModels.
为什么要这样做?好吧,如果您有 50 种类型的实体,每种类型都从不同的值中进行某种选择,那么您只需避免创建 50 个额外的 ViewModel。
回答by David Omid
I thought I'd give my opinion on this, as I've used the ViewBag extensively.
我想我会对此发表意见,因为我已经广泛使用了 ViewBag。
The only real benefits you'll get from using it are for a small project, or in cases where you have a new project and just want to get the ball rolling and not have to worry about creating loads of model classes.
使用它的唯一真正好处是用于小型项目,或者在您有一个新项目并且只想让球滚动而不必担心创建大量模型类的情况下。
When your project is more mature, you may find issues with unexpected behaviour caused by using weak typing all over your application. The logic can be confusing, difficult to test and difficult to troubleshoot when things go wrong.
当您的项目更加成熟时,您可能会发现由于在整个应用程序中使用弱类型而导致的意外行为问题。当出现问题时,逻辑可能会令人困惑、难以测试且难以排除故障。
I actually went down the route of completely removing the ViewBagfrom my applications, and preventing other developers from using it within the same codebase by throwing compilation errors when they try to, even within Razor views.
实际上,我走的是从我的应用程序中完全删除 ViewBag的路线,并通过在尝试时抛出编译错误来阻止其他开发人员在同一代码库中使用它,即使在 Razor 视图中也是如此。
Here's a sample ASP.NET 5 project on GitHub where I've removed it: https://github.com/davidomid/Mvc5NoViewBag
这是 GitHub 上的一个示例 ASP.NET 5 项目,我已将其删除:https: //github.com/davidomid/Mvc5NoViewBag
And here's a blog post where I explain the motivations for removing it and an explanation on how the solution works: https://www.davidomid.com/hate-the-aspnet-mvc-viewbag-as-much-as-i-do-heres-how-to-remove-it
这是一篇博客文章,我解释了删除它的动机以及解决方案如何工作的解释:https: //www.davidomid.com/hate-the-aspnet-mvc-viewbag-as-much-as-i-做这里如何删除它

