我应该始终使用视图模型还是可以使用ViewData?

Cel*_*dor 1 asp.net-mvc viewdata

你觉得什么时候在视图模型上使用ViewData会更好?

我在几个主要视图中有相同的部分视图.我想控制部分视图的渲染方式,但我也更喜欢局部视图只接受视图模型,它是一个记录集合,只是一个纯IEnumerable<>对象.我宁愿避免从主视图发送完整视图模型对象,因为它还包含许多不同的属性,对象,控制分页,排序,过滤等.

因此问题是我是否应该为局部视图创建另一个视图模型,或者是否可以使用ViewData?我读过soemwhere,使用ViewData是一种非常糟糕的做法.

使用View Data,我可以简单地传递需要的详细信息:

@{
    ViewDataDictionary vd = new ViewDataDictionary
    {
        new KeyValuePair<string,object>("WithDelete", Model.WithDelete),
        new KeyValuePair<string,object>("WithRadarCode", Model.WithCode)
    };
}

// ...

@if (Model != null) {
    Html.RenderPartial("_ListOfRecordingsToRender", Model.recordingViewModel, vd);
}
Run Code Online (Sandbox Code Playgroud)

目前,它将被整理出来.

我担心的是,目前*.recordingViewModel我的项目有很多不同的变化,因为创建/编辑,列表,显示记录的细节等不同的模型.我觉得如果我查看我的项目可能会开始太乱每个动作的模型.

你怎么看.请问您能否就这一特定问题提出建议.谢谢

Jam*_*ees 5

我认为你应该坚持使用a ViewModel,你ViewModel的类是定义你对视图的要求.

我背后的原因是,从长远来看,它将更加可维护.当你在视图中使用ViewBag它时dynamic,你应该检查ViewBag属性是否存在(并且可能导致像拼写错误这样的愚蠢错误),例如:

if(ViewBag.PropertyName != null)
{
    // ViewBag.PropertyName is a different property to ViewBag.propertyName
}
Run Code Online (Sandbox Code Playgroud)

这种类型的代码可能会使您的View非常混乱.如果您使用强类型模型,您应该能够将大部分逻辑放在控制器中,并使View尽可能保持干净,这在我的书中是一个巨大的优势.

您也将最终(如果您使用ViewBag)试图在某个时刻维持它并且努力.你正在删除一个关于C#的好东西,它是一种强类型语言!ViewBag不是强类型,你可能认为你传入了一个,List<T>但你可能只是通过一个string.

最后一点,您也将失去Visual Studio中的任何智能感知功能.

如果我为每个动作制作视图模型,我觉得在我的项目中可能会开始变得太乱.

它不会只是在你的控制器中将所有内容分配给一个混乱ViewBag吗?如果是,ViewModel您可以将其发送到"映射"类,以将您的DTO映射到您的视图.

而不是这个:

// ViewModel
var model = new CustomViewModel()
{
    PropertyOne = result.FirstResult,
    PropertyTwo = result.SecondResult,
}
//ViewBag
ViewBag.PropertyOne = result.FirstResult;
ViewBag.PropertyTwo = result.SecondResult;
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

var mapper = new Map();
var model = mapper.MapToViewModel(result);
Run Code Online (Sandbox Code Playgroud)

*你显然需要为映射类提供一个实现,看看类似的东西 Automapper

我也更喜欢局部视图只接受一个视图模型,它是一个记录集合,只是一个纯IEnumerable <>对象.我宁愿避免从主视图发送完整视图模型对象,因为它还包含许多不同的属性,对象,控制分页,排序,过滤等.

没关系,只需创建一个具有属性的视图模型IEnumerable<T>.在我看来,你应该尝试ViewModel在所有场景中使用强类型.