Asp.net mvc ASP.net MVC:在视图或操作中创建SelectList?

Asp.net mvc ASP.net MVC:在视图或操作中创建SelectList?,asp.net-mvc,mvvm,viewmodel,automapper,selectlist,Asp.net Mvc,Mvvm,Viewmodel,Automapper,Selectlist,我只是想知道人们在哪里创建他们的选择列表-在动作或视图中 我已经看到了这两个例子,对我来说最有意义的一个是在动作中执行,并且让视图模型具有SelectList类型的属性 另一方面,我看到过一些示例,其中视图模型的属性为SelectList,SelectList在视图模型中填充(在构造函数中或通过延迟加载)。我喜欢这个想法,因为它意味着在我的行动中有更少的代码 简言之,我只是想知道人们在做什么 干杯安东尼在控制器中创建选择列表(通过从模型存储库中查找项目列表),并将其作为ViewData对象或强类

我只是想知道人们在哪里创建他们的选择列表-在动作或视图中

我已经看到了这两个例子,对我来说最有意义的一个是在动作中执行,并且让视图模型具有SelectList类型的属性

另一方面,我看到过一些示例,其中视图模型的属性为SelectList,SelectList在视图模型中填充(在构造函数中或通过延迟加载)。我喜欢这个想法,因为它意味着在我的行动中有更少的代码

简言之,我只是想知道人们在做什么


干杯安东尼

在控制器中创建选择列表(通过从模型存储库中查找项目列表),并将其作为ViewData对象或强类型ViewModel的一部分传递给视图。

我通常在操作层或服务层中创建我的选择列表,然后通过ViewData将其传递给我的视图。我还将其作为视图模型和强类型视图的一部分。不过,这两种方法都是在操作层或服务层创建它。

我在视图模型中将SelectList作为属性公开,并使用必要的存储库将其填充到操作中。我认为,与存储库直接交互的代码应该也是负责填充的代码,无论是控制器操作还是服务层,或者其他什么


我不认为直接从视图模型填充列表是一个好主意,因为这需要视图模型具有存储库依赖关系并进行数据库交互,而视图模型不应该负责这类事情


如果您有多个SelectList字段,并且希望保持操作代码更干净,您还可以创建一个单独的特殊对象,称为Initializer或类似的东西,来执行所有填充和初始化操作。

这是一个特定于演示文稿的方面,因此我更喜欢在视图中使用Html帮助器来完成。因此,我将一个集合传递给视图,并使用html帮助器方法将项目映射到SelectListItems。该方法可能看起来非常像这样:

public static IList<SelectListItem> MapToSelectItems<T>(this IEnumerable<T> itemsToMap, Func<T, string> textProperty, Func<T, string> valueProperty, Predicate<T> isSelected)
{
    var result = new List<SelectListItem>();

    foreach (var item in itemsToMap)
    {
        result.Add(new SelectListItem
        {
            Value = valueProperty(item),
            Text = textProperty(item),
            Selected = isSelected(item)
        });
    }
    return result;
}
公共静态IList MapToSelectItems(此IEnumerable ItemsMap、Func textProperty、Func valueProperty、谓词isSelected)
{
var result=新列表();
foreach(ItemToMap中的var项目)
{
结果。添加(新的SelectListItem
{
值=值属性(项目),
Text=textProperty(项目),
已选=已选(项目)
});
}
返回结果;
}

问候。

都不是,在单独的类中创建它,请看这里


我在控制器中使用IBuilder接口,并在该构建器的实现中完成所有实体/视图模型的构建

“我认为直接从视图模型填充列表不是一个好主意,因为它需要视图模型具有存储库依赖关系”-不一定。视图模型填充在控制器中(包括SelectList所需的项目列表),因此视图模型本身不需要存储库依赖项。这正是我的观点。存储库填充代码应该从控制器中调用,而不是从视图模型代码(构造函数或其他方法)中调用。您仍然需要在ViewModel中创建一个项目列表,为什么不将其设置为SelectList呢?您是对的,我认为模型只是一个实体或从实体转换而来的dto(不作为视图特定模型或视图模型),无论如何,您可以使用上面的方法进行转换。我认为视图特定的模型可能应该直接公开一个SelectList,因为它减少了您必须在视图中编写的代码量,即使只是一点点。但在某些情况下,我会将DTO或业务对象传递给视图,在这些情况下,我会调用您所展示的帮助程序我认为这两种方法都适用于不同的场景。我不喜欢在控制器中(或在将BO转换为ViewModel的类中)创建SelectList,因为有时您需要添加虚拟选项,如“选择一个”或“无”,等等。如果您的应用程序要本地化,那么您应该从一个资源文件中选取此文本,因为它会影响特定操作的测试。通过ViewData传递SelectList是可以的,但是如果您的页面强类型化为ViewModel对象,则只需将SelectList包含在其中作为测试的一部分,就更干净了ViewModel.Congregated,如果需要向视图发送更多数据而不仅仅是选择列表,我会这么做。如果我只需要选择列表,那么我倾向于使用ViewData。为什么?如果您提供一些更详细的信息,说明为什么您认为此方法更可取,我会很乐意投票。是否更容易测试?促进代码重用?更好地分离关注点?@Seth:强类型ViewModel对象的目的是打包视图所需的所有数据,以便正确呈现视图。在这种情况下,由于下拉列表需要项目列表,因此将其包含在ViewModel对象中是合适的。在我之后的程序员将在ViewModel中看到SelectList,并得出结论它被用来填充视图中的下拉列表。他不必查看其他任何地方。@Robert:我完全同意你的观点。我的观点是你的答案被选为“正确”一个,我认为一些额外的信息可能会对将来遇到这个问题的人有所帮助。我希望新的MVC程序员知道为什么这更可取,而不是盲目地遵循这样一个答案:)@Seth:完全正确。当时,我只有时间回答问题,没有发言权。谢谢提醒。您不能将SelectList属性作为强类型ViewModel的一部分,因为它将抛出“无参数构造函数”错误。