我已经开始使用MVC 3,我真的很喜欢使用它。在很多层面上,它比WebForms好得多。
但是我对ViewBag(新的ViewData)有疑问 我非常谨慎地坚持声音建模实践,我倾向于将我的视图所需的所有内容都放到ViewModels中。然而,就ViewBag而言,除了糟糕的建模实践之外是否有任何其他问题表明应该谨慎使用ViewBag?我自己并没有太多使用它,但今天队友问了这个问题,我只能建议限制它的使用,因为它是一个弱类型的模型,使用动态(sudo typed)被黑客攻击很酷
形成我所知道的,虽然使用它不会对性能产生任何影响吗? 我对吗?它只是另一个被应用于视图服务器端的对象。 我没有计算使用动态的任何性能影响(如果有一个可以测量的)
您对使用ViewBag的缺点(甚至优势)有何看法?
答案 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!