[英]Pass SelectList “SelectedValue” to Controller Action Method
我有一个注册表单,其中显示了用户名(文本框),电子邮件(文本框)和部门(SelectList)。 名称和电子邮件已预先填充(我正在使用Windows身份验证,Intranet应用程序),并且我希望将Dropdown中的SelectedValue作为Int32发送到我的控制器,我不想将整个SelectList发送回去。 该列表现在很小,但是将会增长到可观的规模。
我的类称为RegistrationViewModel
,它包含这些字段的公共属性。 但是,当我将SelectList
用于DivisionList时,会收到此错误: No parameterless constructor defined for this object.
。
如果我更改Type,则没问题,但是Division为null或0。是否可以将SelectedValue从DropDown传递给Int32的Controller Action方法?
我不确定自己在做什么,我已经使用MVC约48个小时,观看了PDF,TechEd和TechDays视频。
抱歉,这是我的控制器代码:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Register(RegistrationViewModel rvm)
{
IApplicationContext context = ContextRegistry.GetContext();
IValidationErrors errors = new ValidationErrors();
IValidator validator = (IValidator)context.GetObject("RegistrationValidator");
bool valid = validator.Validate(rvm, errors);
if (valid)
repo.SaveRegistration();
else
ViewData["DivisionList"] = repo.GetDivisions();
return View(rvm);
}
RegistrationViewModel
类
public class RegistrationViewModel
{
public string Name { get; set; }
public string Email { get; set; }
//public SelectList DivisionList { get; private set; }
public int Division { get; set; }
}
这是视图
<%@ Page Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<RegistrationViewModel>" %>
<%@ Import Namespace="Project1.Entities"%>
<%@ Import Namespace="Project1.Models"%>
<asp:Content ID="registerTitle" ContentPlaceHolderID="TitleContent" runat="server">
Register
</asp:Content>
<asp:Content ID="registerContent" ContentPlaceHolderID="MainContent" runat="server">
...
<% using (Html.BeginForm())
{ %>
<div>
<fieldset>
<legend>Account Information</legend>
<p>
<label for="name">Name:</label>
<%= Html.TextBox("Name", User.Identity.Name.GetDisplayName()) %>
<%= Html.ValidationMessage("username") %>
</p>
<p>
<label for="email">Email:</label>
<%= Html.TextBox("email", User.Identity.Name.GetEmailFromLogin()) %>
<%= Html.ValidationMessage("email") %>
</p>
<p>
<label for="division">Division:</label>
<%= Html.DropDownList("DivisionList", ViewData["DivisionList"] as SelectList)%>
<%= Html.ValidationMessage("confirmPassword") %>
</p>
<p>
<input type="submit" value="Register" />
</p>
</fieldset>
</div>
<% } %>
</asp:Content>
Eilon:这也是我所做的更改:
控制器:
public ActionResult Register()
{
ViewData["DivisionList"] = repo.GetDivisions();
return View();
}
视图:
<%= Html.DropDownList("DivisionValue", ViewData["DivisionList"] as SelectList)%>
我收到此异常:没有键类型为“ DinumValue”的“ IEnumerable”类型的ViewData项目。
当我将视图更新为:
<%= Html.DropDownList("DivisionList", ViewData["DivisionList"] as SelectList)%>
效果很好! 如果所有“部门”项目都相同地命名,这似乎才起作用。 如果更改名称,则视图崩溃或ViewModel的“ Division”属性发送为0。
这是为什么?
RegistrationViewModel类型应包含一个简单类型的属性,例如:
public string DivisionValue { get; set; }
或将类型更改为int,DateTime或任何适当的类型。
在HTML和HTTP中,唯一返回到下拉列表的内容是字段名称和所选值。
为了使所有内容匹配,还需要更改视图以为下拉列表呈现不同的输入名称:
<%= Html.DropDownList("DivisionValue", ViewData["DivisionList"] as SelectList)%>
请注意,我使用“DivisionValue”是列表的价值 ,并作为DivisionList所有可用项的列表。
我只是对SelectList
类型更明确。 我建议在控制器动作中创建SelectList
,而SelectList
在视图中进行转换。 我的代码如下所示(“ CRUD编辑”页面):
..在动作中:
ViewData["WorkType.ID"] = new SelectList(this._vacancySvc.GetVacancyWorkTypes(),
"ID", "Name", ViewData["WorkType.ID"] ?? vacancy.WorkType.ID);
..并在视图中:
<p><% =Html.Encode("Work Type:") %><br />
<% =Html.DropDownList("Worktype.ID")%><span class="smallgrey">(required)</span><br />
..您可以看到,通过使用[null合并运算符] [1](??),持久化了初始选择(来自数据库)或来自回发的ViewData(例如,表单验证失败)。
此外,如果我重构此代码,则可能会像您一样使用ViewModel对象。 唯一的事情是:(1)您永远不需要在视图视图中引用ViewModel SelectList
属性Html.DropDownList()
通过Html.DropDownList()
重载为我们自动绑定此视图。和(2)我仍然需要引用无论如何,操作中的ViewData都会从失败的验证帖子中获取选定的值,那么真正的意义是什么?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.