2012-03-30 98 views
1

我已經開始使用MVC 3,我非常喜歡使用它。在許多層面上,這比WebForms更好的體驗。ViewBag中的對象

但是我有一個關於ViewBag(新ViewData)的問題 我非常小心地堅持聲音建模實踐,我傾向於將視圖需要的所有東西放到ViewModels中。然而,就ViewBag而言,除了糟糕的建模實踐之外,是否還有其他顧慮,表明應該謹慎使用ViewBag?我自己並沒有太多的使用它,但是隊友今天提出了這個問題,我只能推薦限制它的使用,因爲它是一個弱類型模型,被動態地使用動態(sudo類型)

我可以告訴那裏使用它不應該有任何性能影響? 我對不對?這只是另一個應用於視圖服務器端的對象。 我不指望使用動態的任何性能影響(如果有一個可以測量的)

對於使用ViewBag的缺點(甚至是優點),您有什麼看法?

回答

2

對我來說,最大的問題是ViewBag不是類型安全的,如果你不小心的話,很容易產生運行時錯誤。

視圖包真的只是一個方便,以防止簡單的情況下,否則你需要一個新的視圖模型。我經常使用它們,但僅限於非常簡單的數據。

+0

是的,我同意,這似乎很像一個好地方到另一個地方追悔沒來,當你做你的視圖模型,或者沒有適合。我通常將它用於簡單的事情,如int或其他一些簡單的對象。 – TGH 2012-03-30 04:37:24

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! 
相關問題