Asp.net mvc ASP.NET MVC Html.DropDownList SelectedValue
我尝试过这是RC1,然后升级到RC2,但没有解决问题Asp.net mvc ASP.NET MVC Html.DropDownList SelectedValue,asp.net-mvc,Asp.net Mvc,我尝试过这是RC1,然后升级到RC2,但没有解决问题 // in my controller ViewData["UserId"] = new SelectList( users, "UserId", "DisplayName", selectedUserId.Value); // this has a value 结果:在对象上设置SelectedValue属性 // in my view <%=Html.DropDownList("UserId"
// in my controller
ViewData["UserId"] = new SelectList(
users,
"UserId",
"DisplayName",
selectedUserId.Value); // this has a value
结果:在对象上设置SelectedValue属性
// in my view
<%=Html.DropDownList("UserId", (SelectList)ViewData["UserId"])%>
//在我看来
结果:所有预期选项都呈现给客户端,但未设置选定属性。SelectedValue中的项目存在于列表中,但列表中的第一个项目始终默认为selected
我应该怎么做
更新
多亏了约翰·费米内拉的回答,我才发现了问题所在。“UserId”是我的视图强类型化到的模型中的一个属性。当Html.DropDownList(“UserId”更改为除“UserId”之外的任何其他名称时,所选值将正确呈现
但这会导致值未绑定到模型。请尝试以下操作:
public class Person {
public int Id { get; set; }
public string Name { get; set; }
}
然后:
var list = new[] {
new Person { Id = 1, Name = "Name1" },
new Person { Id = 2, Name = "Name2" },
new Person { Id = 3, Name = "Name3" }
};
var selectList = new SelectList(list, "Id", "Name", 2);
ViewData["People"] = selectList;
Html.DropDownList("PeopleClass", (SelectList)ViewData["People"])
通过MVC RC2,我得到:
<select id="PeopleClass" name="PeopleClass">
<option value="1">Name1</option>
<option selected="selected" value="2">Name2</option>
<option value="3">Name3</option>
</select>
名称1
姓名2
名字3
这似乎是SelectExtensions类中的一个错误,因为它只会检查所选项目的ViewData而不是模型。因此,诀窍是将所选项目从模型复制到属性名称下的ViewData集合中
这是我在MVC论坛上给出的答案,我也有一个更完整的答案,使用
给出一个模型
public class ArticleType
{
public Guid Id { get; set; }
public string Description { get; set; }
}
public class Article
{
public Guid Id { get; set; }
public string Name { get; set; }
public ArticleType { get; set; }
}
和一个基本的视图模型
public class ArticleModel
{
public Guid Id { get; set; }
public string Name { get; set; }
[UIHint("DropDownList")]
public Guid ArticleType { get; set; }
}
然后我们编写一个DropDownList编辑器模板,如下所示
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<script runat="server">
IEnumerable<SelectListItem> GetSelectList()
{
var metaData = ViewData.ModelMetadata;
if (metaData == null)
{
return null;
}
var selected = Model is SelectListItem ? ((SelectListItem) Model).Value : Model.ToString();
ViewData[metaData.PropertyName] = selected;
var key = metaData.PropertyName + "List";
return (IEnumerable<SelectListItem>)ViewData[key];
}
</script>
<%= Html.DropDownList(null, GetSelectList()) %>
IEnumerable GetSelectList()
{
var metaData=ViewData.ModelMetadata;
if(元数据==null)
{
返回null;
}
var selected=模型是SelectListItem?((SelectListItem)模型)。值:Model.ToString();
ViewData[metaData.PropertyName]=已选择;
var key=metaData.PropertyName+“列表”;
返回(IEnumerable)视图数据[键];
}
如果您将视图模型中的ArticleType更改为SelectListItem,这也会起作用,尽管您必须按照Kazi的博客实现一个类型转换器并注册它,以强制绑定器将其视为简单类型
在你的控制器中,我们有
public ArticleController
{
...
public ActionResult Edit(int id)
{
var entity = repository.FindOne<Article>(id);
var model = builder.Convert<ArticleModel>(entity);
var types = repository.FindAll<ArticleTypes>();
ViewData["ArticleTypeList"] = builder.Convert<SelectListItem>(types);
return VIew(model);
}
...
}
公共控制器
{
...
公共操作结果编辑(int id)
{
var entity=repository.FindOne(id);
var model=builder.Convert(实体);
var types=repository.FindAll();
ViewData[“ArticleTypeList”]=builder.Convert(类型);
返回视图(模型);
}
...
}
我就是这样解决这个问题的:
我有以下几点:
控制器:
ViewData["DealerTypes"] = Helper.SetSelectedValue(listOfValues, selectedValue) ;
看法
更改如下:
看法
看起来,下拉框的名称不能与ViewData的名称相同,但它工作起来很奇怪。问题在于,下拉框的工作方式与列表框不同,至少与ASP.NET MVC2设计所期望的方式不同:下拉框只允许零或一个值,因为列表框可以有多个值选择。因此,严格使用HTML时value不应该作为“selected”标志出现在选项列表中,而应该出现在输入本身中 请参见以下示例:
<select id="combo" name="combo" value="id2">
<option value="id1">This is option 1</option>
<option value="id2" selected="selected">This is option 2</option>
<option value="id3">This is option 3</option>
</select>
<select id="listbox" name="listbox" multiple>
<option value="id1">This is option 1</option>
<option value="id2" selected="selected">This is option 2</option>
<option value="id3">This is option 3</option>
</select>
这是选项1
这是选项2
这是选项3
这是选项1
这是选项2
这是选项3
组合框选择了选项,但也设置了其值属性。因此,如果希望ASP.NET MVC2呈现dropbox并选择特定值(即默认值等),则应在呈现时为其指定一个值,如下所示:
// in my view
<%=Html.DropDownList("UserId", selectListItems /* (SelectList)ViewData["UserId"]*/, new { @Value = selectedUser.Id } /* Your selected value as an additional HTML attribute */)%>
//在我看来
在ASP.NET MVC 3中,您只需将列表添加到ViewData
var options = new List<SelectListItem>();
options.Add(new SelectListItem { Value = "1", Text = "1" });
options.Add(new SelectListItem { Value = "2", Text = "2" });
options.Add(new SelectListItem { Value = "3", Text = "3", Selected = true });
ViewData["options"] = options;
您不必在DropDownList调用中手动“使用”列表。这样做也可以为我正确设置所选值
免责声明:
上一篇MVC 3文章中的代码不起作用,但这是一个很好的开始。我会修复它。我已经测试了这段代码,它在MVC 3 Razor C中工作。这段代码使用ViewModel模式填充返回
列表的属性
模范班
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
}
using System.Web.Mvc;
public class ProductListviewModel
{
public List<SelectListItem> Products { get; set; }
}
ViewModel类
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
}
using System.Web.Mvc;
public class ProductListviewModel
{
public List<SelectListItem> Products { get; set; }
}
HTML输出类似于
<select id="Products" name="Products">
<option value="3">Product: Widget 10.00</option>
<option value="4">Product: Gadget 5.95</option>
</select>
产品:Widget 10.00
产品:Gadget 5.95
取决于您如何格式化输出。我希望这会有所帮助。代码确实有效。您仍然可以将下拉列表命名为“UserId”,并且模型绑定仍然可以正常工作
此操作的唯一要求是,包含SelectList的ViewData键与要绑定的模型属性的名称不同。在您的特定情况下,这可能是:
// in my controller
ViewData["Users"] = new SelectList(
users,
"UserId",
"DisplayName",
selectedUserId.Value); // this has a value
// in my view
<%=Html.DropDownList("UserId", (SelectList)ViewData["Users"])%>
//在我的控制器中
ViewData[“用户”]=新建选择列表(
用户,
“用户ID”,
“显示名称”,
selectedUserId.Value);//这有一个值
//在我看来
这将生成一个名为UserId的select元素,该元素与模型中的UserId属性具有相同的名称,因此模型绑定器将使用html.DropDownList帮助程序生成的html的select元素中选择的值对其进行设置
我不知道为什么当您在ViewData中使用与属性名相等的键放置选择列表时,特定的Html.DropDownList构造函数不会选择SelectList中指定的值。我怀疑这与DropDownList帮助器在其他场景中的使用方式有关,在其他场景中,惯例是您有一个SelectList在ViewData中使用与模型中的属性相同的名称。这将正常工作:
// in my controller
ViewData["UserId"] = new SelectList(
users,
"UserId",
"DisplayName",
selectedUserId.Value); // this has a value
// in my view
<%=Html.DropDownList("UserId")%>
//在我的控制器中
ViewData[“UserId”]=新建选择列表(
用户,
“用户ID”,
“显示名称”,
selectedUserId.Value);//这有一个值
//在我看来
如果我们不认为这是团队应该修复的错误,至少MSDN应该改进文档。令人困惑的真正原因是这篇糟糕的文档。在本文中,它解释了参数<
<select id="Products" name="Products">
<option value="3">Product: Widget 10.00</option>
<option value="4">Product: Gadget 5.95</option>
</select>
// in my controller
ViewData["Users"] = new SelectList(
users,
"UserId",
"DisplayName",
selectedUserId.Value); // this has a value
// in my view
<%=Html.DropDownList("UserId", (SelectList)ViewData["Users"])%>
// in my controller
ViewData["UserId"] = new SelectList(
users,
"UserId",
"DisplayName",
selectedUserId.Value); // this has a value
// in my view
<%=Html.DropDownList("UserId")%>
Type: System.String
The name of the form field to return.
public class Person {
public int Id { get; set; }
public string Name { get; set; }
}
public class PersonsSelectViewModel{
public string SelectedPersonId,
public List<SelectListItem> Persons;
}
private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, ModelMetadata metadata,
string optionLabel, string name, IEnumerable<SelectListItem> selectList, bool allowMultiple,
IDictionary<string, object> htmlAttributes)
{
...
bool usedViewData = false;
// If we got a null selectList, try to use ViewData to get the list of items.
if (selectList == null)
{
selectList = htmlHelper.GetSelectData(name);
usedViewData = true;
}
object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string));
// If we haven't already used ViewData to get the entire list of items then we need to
// use the ViewData-supplied value before using the parameter-supplied value.
if (defaultValue == null && !String.IsNullOrEmpty(name))
{
if (!usedViewData)
{
defaultValue = htmlHelper.ViewData.Eval(name);
}
else if (metadata != null)
{
defaultValue = metadata.Model;
}
}
if (defaultValue != null)
{
selectList = GetSelectListWithDefaultValue(selectList, defaultValue, allowMultiple);
}
...
return tagBuilder.ToMvcHtmlString(TagRenderMode.Normal);
}
if ((defaultValue != null) && (!selectList.Any(i=>i.Selected)))
{
selectList = GetSelectListWithDefaultValue(selectList, defaultValue, allowMultiple);
}
@Html.DropDownList("Example", new SelectList(Model.FeeStructures, "Id", "NameOfFeeStructure", Model.Matters.FeeStructures))