MVC ViewBag Best Practice

前端 未结 10 1856
野趣味
野趣味 2020-11-29 01:42

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?

Question:

  1. <
相关标签:
10条回答
  • 2020-11-29 02:00

    1) Is my assumption above the best practice. (Not to use a ViewBag and second to have it in the view model)

    You should use viewmodels instead of passing data via ViewBag as much as possible.

    2) Are there situations where a ViewBag is absolutely necessary?

    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.

    0 讨论(0)
  • 2020-11-29 02:00

    1) Is my assumption above the best practice. (Not to use a ViewBag and second to have it in the view model)

    Yes.

    2) Are there situations where a ViewBag is absolutely necessary?

    No. Everything that you have stored in a ViewBag could go into the view model passed to the view.

    0 讨论(0)
  • 2020-11-29 02:01
    1. No. Use ViewModels.
    2. No. If you design a perfect ViewModel, you never need a ViewBag.
    0 讨论(0)
  • 2020-11-29 02:03

    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 :(

    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.

    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 post with example code on how to do that.

    Are there situations where a ViewBag is absolutely necessary?

    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.

    public ActionResult Create()
    {
       ViewBag.AnnouncementForEditors="Be careful";
       return View();
    }
    

    And in the layout, you can read the ViewBag.AnnouncementForEditors

    <body>
    <h1>@ViewBag.AnnouncementForEditors</h1>
    <div class="container body-content">
        @RenderBody()
    </div>
    </body>
    
    0 讨论(0)
  • 2020-11-29 02:07

    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>.

    Sticking to view models is best, even if you have to alter them to fit a specific view now and again.

    0 讨论(0)
  • 2020-11-29 02:09

    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 lot of fluff to your tests. I don't think it is worth it in this situation.

    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.

    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.

    Erick

    0 讨论(0)
提交回复
热议问题