Asp.net mvc MVC ViewBag最佳实践
对于ViewBag,我听说这是一个禁止使用的选项。 我假设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在操作方法和视图之间传输数据时,如果您在试图访问视图中的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>