ViewBag中的对象

时间:2012-03-30 04:32:29

标签: c# asp.net asp.net-mvc-3

我已经开始使用MVC 3,我真的很喜欢使用它。在很多层面上,它比WebForms好得多。

但是我对ViewBag(新的ViewData)有疑问 我非常谨慎地坚持声音建模实践,我倾向于将我的视图所需的所有内容都放到ViewModels中。然而,就ViewBag而言,除了糟糕的建模实践之外是否有任何其他问题表明应该谨慎使用ViewBag?我自己并没有太多使用它,但今天队友问了这个问题,我只能建议限制它的使用,因为它是一个弱类型的模型,使用动态(sudo typed)被黑客攻击很酷

形成我所知道的,虽然使用它不会对性能产生任何影响吗? 我对吗?它只是另一个被应用于视图服务器端的对象。 我没有计算使用动态的任何性能影响(如果有一个可以测量的)

您对使用ViewBag的缺点(甚至优势)有何看法?

2 个答案:

答案 0 :(得分:2)

对我来说,最大的问题是ViewBag不是类型安全的,如果你不小心,很容易产生运行时错误。

视图包实际上只是为了防止您需要新视图模型的简单情况。我经常使用它们,但仅用于非常简单的数据。

答案 1 :(得分:0)

来自我的帖子: http://completedevelopment.blogspot.com/2011/12/stop-using-viewbag-in-most-places.html

Even the built in templates give us support for ViewBag. The scaffolding templates create ViewBag.SomeEnumerable to use for our pages.
Sure - its quick code and since it's auto-generated will likely work ok. The problem comes in from the fact that ViewBag is a dynamic object. There are no compile time type checks. If you misspell something you won't be notified from the compiler.

I've seen this used in such bad ways, I would love to see it's usage curbed and applications cleaned up. 

So in a controller:
ViewBag.SomeProperty = "10"
and in the view:
@ViewBag.Som3Pr0p3rty
We won't ever know of this error. It won't even generate a runtime error since the misspelled name just generated a null.


Use ViewModels and save yourself from these potential problems. Our templates set a page title in ViewBag as well.


There are several options in setting a page title. Since this is a well known property one could argue that using it just for Title is ok. I wouldn't argue this. There are other options.
1. Set it in a section in the layout and render it from the client.
2. Use ViewBag.Title
3. Use a filter (seems much too complicated for a title)
4. Use a Model.Title field.

Since by default we have a ViewBag.Title field created and our templates also get it by default, I'll yield that in this case, its ok.

What about select lists?
Rather than the default 

 ViewBag.CustomerId = new SelectList(db.Customers, "CustomerId", "FirstName", order.CustomerId);


Do something like
yourViewModel.Customers = customers; //a loaded collection

and in your view
@Html.DropDownListFor(x => x.CustomerId, new SelectList(Model.Customers, "CustomerId", "Name"))

Or if you prefer to set your ViewModel to contain the SelectList


yourViewModel.Customers = new SelectList(db.Customers, "CustomerId", "Name", order.CustomerId);

and now your view would be slightly cleaner as:
@Html.DropDownListFor(x => x.CustomerId, x.Customers)

See, that's not so difficult now is it? Enjoy!