Asp.net mvc MVC ViewBag最佳实践

Asp.net mvc MVC ViewBag最佳实践,asp.net-mvc,razor,viewbag,Asp.net Mvc,Razor,Viewbag,对于ViewBag,我听说这是一个禁止使用的选项。 我假设ViewBag中的内容应该合并到视图模型中 问题: 是我的假设高于最佳实践。(不使用ViewBag,第二种方法是将其包含在视图模型中) 是否存在绝对需要查看包的情况 不,用 不需要。如果你设计了一个完美的ViewModel,你永远不需要ViewBag 1) 是我的假设高于最佳实践。(不要使用可视包和 第二种方法是将其放在视图模型中) 对 2) 是否存在绝对需要查看包的情况 否。存储在ViewBag中的所有内容都可以进入传递给视图的视图模型

对于ViewBag,我听说这是一个禁止使用的选项。 我假设ViewBag中的内容应该合并到视图模型中

问题:

  • 是我的假设高于最佳实践。(不使用ViewBag,第二种方法是将其包含在视图模型中)

  • 是否存在绝对需要查看包的情况

  • 不,用
  • 不需要。如果你设计了一个完美的ViewModel,你永远不需要ViewBag
  • 1) 是我的假设高于最佳实践。(不要使用可视包和 第二种方法是将其放在视图模型中)

    2) 是否存在绝对需要查看包的情况


    否。存储在ViewBag中的所有内容都可以进入传递给视图的视图模型。

    ViewBag是一个动态字典。因此,当使用ViewBag在操作方法和视图之间传输数据时,如果您在试图访问视图中的ViewBag项时在代码中输入了错误,编译器将无法捕获。您的视图将在运行时崩溃:(

    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);
    }
    
    通常,使用视图模型在操作方法和视图之间传输数据是一个好主意。视图模型是一个简单的POCO类,具有特定于视图的属性。因此,如果要向视图传递一些附加数据,请向视图模型添加一个新属性并使用该属性。强类型视图使代码更清晰,更易于管理使用这种方法,您不需要将viewbag字典项显式地来回转换为与viewbag相关的某些类型

    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;}
    }
    
    在布局中,您可以阅读
    ViewBag.AnnouncementForEditors

    <body>
    <h1>@ViewBag.AnnouncementForEditors</h1>
    <div class="container body-content">
        @RenderBody()
    </div>
    </body>
    
    
    @ViewBag.AnnouncementForEditors
    @RenderBody()
    
    ViewBags的问题和推荐的最佳实践归结为编译时检查。ViewBags只是字典,因此,如果您最终更改了其中一个viewbag项的对象类型或键名,则即使使用
    true
    预编译视图,也要等到运行时才能知道

    坚持视图模型是最好的,即使您必须时不时地修改它们以适应特定的视图

    1) 是我的假设高于最佳实践。(不要使用可视包和 第二种方法是将其放在视图模型中)

    您应该尽可能使用viewmodels,而不是通过ViewBag传递数据

    2) 是否存在绝对需要查看包的情况


    没有绝对需要ViewBag的情况。然而,有些数据我个人更喜欢使用ViewBag而不是视图模型。例如,当我需要为预定义值(即城市)填充下拉框时,我使用ViewBag携带SelectListItem数组进行查看。我不想让这些数据污染我的ViewModels。

    我发现ViewBag在所有页面上都有通用功能,并且该功能不依赖于显示的页面的情况下有一些用处。例如,假设您正在构建StackOverflow。每个页面上都会显示作业板,但显示的作业与页面无关(我的用法在概念上类似)。向每个ViewModel添加属性既困难又耗时,而且会给测试带来很多麻烦。我认为在这种情况下不值得这么做

    我使用了一个带有横切数据的基本ViewModel类,但如果您有多个(例如,作业和堆栈交换站点列表),则必须开始填充额外的数据,或者滥用ViewModel,另外还需要一个ViewModel builder来填充基本数据

    至于魔弦问题,有很多解决方案。常量、扩展方法等

    综上所述,如果页面上显示的内容取决于页面的上下文,那么ViewModel就是您的朋友


    Erick

    如果无法重新设计现有的ViewModel,请使用ViewBag

    2.是否存在绝对需要查看包的情况


    在某些情况下,您需要在布局、视图和局部视图之间共享来自控制器的数据。在这种情况下,ViewBag非常有用,我怀疑有没有更好的方法。

    如果没有它的用例,它就不会在第一时间实现。是的,你可以用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>
    
    @model categorydo
    (“类别名称”)
    
    但是,如果要选择类别父项,该怎么办?实体DTO理想情况下只保存自己的值,所以要填充选择列表,请使用ViewBag

    <select asp-for="ParentId" asp-items="ViewBag.ParentList">
        <option value="">None</option>
    </select>
    
    
    没有一个
    

    为什么要这样做?如果你有50种类型的实体,每种实体都有不同的值,你只需要避免创建50个额外的ViewModels。

    我想我会给出我的意见,因为我已经广泛使用了ViewBag

    使用它的唯一真正好处是用于一个小项目,或者您有一个新项目,只想开始工作,而不必担心创建模型类的负载

    当您的项目更成熟时,您可能会发现由于在应用程序中使用弱类型而导致的意外行为问题。当出现问题时,逻辑可能会令人困惑,难以测试和排除故障

    实际上,我一直在从我的应用程序中完全删除ViewBag,并阻止其他开发人员在同一代码库中使用它,因为他们在尝试时抛出编译错误,即使在Razor视图中也是如此

    下面是我在GitHub上删除的ASP.NET 5项目示例:

    下面是一篇博客文章,我解释了删除它的动机,并解释了解决方案的工作原理:

    从Microsoft的角度来看,我们不同意“从不使用ViewBag”或“不使用ViewBag”。使用ViewBag传递模型数据是另一回事,应予以折扣
    @model CategoryDto
    <div class="md-form form-sm">
        <input asp-for="Name" class="form-control">
        <label asp-for="Name">("Category Name")</label>
    </div>
    
    <select asp-for="ParentId" asp-items="ViewBag.ParentList">
        <option value="">None</option>
    </select>