繁体   English   中英

将SelectList“ SelectedValue”传递给控制器​​操作方法

[英]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方法?

编辑1:

我不确定自己在做什么,我已经使用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>

编辑2:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM