在EditorTemplate中DropDownListFor没有选择值

kme*_*hta 50 asp.net-mvc

我有一个自定义对象的编辑器模板.在该编辑器模板中,我使用了几个DropDownListFor帮助器.在每个中我指定一个唯一的模型属性(具有预先选择的值)和包含所有选择选项的选择列表.

例:

<%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %>
Run Code Online (Sandbox Code Playgroud)

我知道正在填充选项值(来自查看源),并且我的模型使用正确的ID值(DocumentCategoryType)传入.

渲染视图时,我的下拉列表中没有选定的项目,因此默认为第一个(未选中)值.

有没有人有任何想法?

谢谢.

Cur*_*uys 28

我们还通过填充SelectList具有适当SelectListItem选择的新解决方案来解决该解决方案,但创建了此扩展方法以使调用DropDownListFor更加清洁:

public static SelectList MakeSelection(this SelectList list, object selection)
{
    return new SelectList(list.Items, list.DataValueField, list.DataTextField, selection);
}
Run Code Online (Sandbox Code Playgroud)

然后你的DropDownListFor电话变成:

<%= Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList.MakeSelection(Model.DocumentCategoryType)) %>
Run Code Online (Sandbox Code Playgroud)


Rus*_*Cam 18

浏览ASP.NET MVC 2源代码揭示了这个问题的一些解决方案.从本质上讲,任何SelectListItemSelectList在具有辅助扩展方法传递Selected属性设置为true没有在任何方位<option>与所呈现的元素selected所申请的项目属性.

元素的selected属性<option>由.确定

1)检查辅助扩展方法是否通过了a SelectList.如果为null,则框架将在ViewData中查找与要为其呈现下拉列表的视图模型属性的键对应的值.如果值为a SelectList,则<select>只要model属性的模型状态为null ,这将用于呈现包含任何选定值的包含.

2)如果SelectList已在辅助扩展方法中传递了一个并且model属性的模型状态为null,则框架将使用模型属性名称作为键在ViewData中查找默认值.视图数据中的值将转换为字符串,并且SelectList传递给帮助程序扩展方法的任何项目具有一个值(如果未设置任何值,则将检查文本),该项目的Selected属性设置为true,反过来将<option>使用属性呈现an selected="selected".

把它放在一起,有两个合理的选项,我可以看到选择一个选项并使用强类型DropDownListFor:

使用以下视图模型

public class CategoriesViewModel
{
    public string SelectedCategory { get; private set ; }
    public ICollection<string> Categories { get; private set; }

    public CategoriesViewModel(string selectedCategory, ICollection<string> categories)
    {
        SelectedCategory = selectedCategory;
        Categories = categories;
    }
}
Run Code Online (Sandbox Code Playgroud)

选项1

在控制器的ViewData中设置一个值,使您的视图键入用于呈现下拉列表的集合的属性名称

控制器动作

public class CategoriesController
{
    [HttpGet]
    public ViewResult Select()
    {
        /* some code that gets data from a datasource to populate the view model  */
        ICollection<string> categories = repository.getCategoriesForUser();
        string selectedCategory = repository.getUsersSelectedCategory();

        CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories);
        this.ViewData["Categories"] = selectedCategory;        

        return View(model);
    }

    [HttpPost]
    public ActionResult Select(CategoriesViewModel model)
    {
        /* some code that does something */
    }
}
Run Code Online (Sandbox Code Playgroud)

并且在强类型视图中

<%: Html.DropDownListFor(m => m.Categories, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %>
Run Code Online (Sandbox Code Playgroud)

选项2

使用所选项的属性名称呈现下拉列表

控制器动作

public class CategoriesController
{
    [HttpGet]
    public ViewResult Select()
    {
        /* some code that gets data from a datasource to populate the view model  */
        ICollection<string> categories = repository.getCategoriesForUser();
        string selectedCategory = repository.getUsersSelectedCategory();

        CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories);

        return View(model);
    }

    [HttpPost]
    public ActionResult Select(CategoriesViewModel model)
    {
        /* some code that does something */
    }
}
Run Code Online (Sandbox Code Playgroud)

并且在强类型视图中

<%: Html.DropDownListFor(m => m.SelectedCategory, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %>
Run Code Online (Sandbox Code Playgroud)


Ale*_*ran 14

它被确认为一个bug @ aspnet.codeplex.com,对于强类型视图只有这样的行为.

解决方法:在视图代码中填充SelectList

喜欢

<%= Html.DropDown("DocumentCategoryType", new SelectList(Model.Categories,"id","Name",Model.SelectedCategory")) =>
Run Code Online (Sandbox Code Playgroud)


kme*_*hta 6

呸.我最终解决了这个问题.我希望RTM能解决这个问题.

   <%if(Model!=null){ %>
        <%= Html.DropDownListFor(m => m.DocumentCategoryType, new SelectList(Model.DocumentCategoryTypeList,"Value","Text", Model.DocumentCategoryType))%>
        <%}else{%>
            <%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %>
        <%}%>
Run Code Online (Sandbox Code Playgroud)