从视图传递选定的下拉列表值到控制器

4

我希望从视图中向我的控制器传递一个参数(字符串)。该值应为从视图中的下拉列表中选择的值。该方法在按钮单击后调用,但在控制器中,该参数始终为空。

在视图中:

    @using (Html.BeginForm("Send", "Overview", FormMethod.Get))
    {
        <p>Email: @Html.DropDownList("Emails", Model.GetEmails())
        <input type="submit" value="Send" />
        </p>

    }

在控制器中:

    public ActionResult Send(string email)
    {
        // email is always null!
        return null;
    }

在概述模型中:
    private List<SelectListItem> emails;
    ...
    public Overview()
    {
        emails = new List<SelectListItem>();
        emails.Add(new SelectListItem() { Text = "a@b.com", Value = "a@b.com", Selected = true });
        emails.Add(new SelectListItem() { Text = "b@c.com", Value = "b@c.com", Selected = false });
        emails.Add(new SelectListItem() { Text = "c@d.com", Value = "c@d.com", Selected = false });
    }
    ...
    public List<SelectListItem> GetEmails()
    {
        return emails;
    }

你能帮我完成这个工作吗?我漏掉了什么吗? (顺便说一下,请暂时不要考虑控制器返回 null 的问题:)


这似乎解决了问题,在控制器中:string email2 = Request.Form["Emails"]; - user3147607
为什么GetEmails()是公共的,而且为什么要返回一个List<>?这两个看起来非常像反模式。 - George Mauer
2个回答

7
根据您的术语,我猜测您对正在发生的事情感到困惑。您从未将任何内容从视图发送到控制器。相反,视图是一种组装Html以发送到Web浏览器的东西。因此,实际发生的情况如下:
- 您的浏览器从服务器(IIS)请求`/MyApp/Overview` - IIS将其捡起并发送给Asp.Net - Asp.Net Mvc看到请求,并通过路由确定您要调用`MyAppController`类上的`Overview`方法 - 方法运行并生成模型 - Asp.Net Mvc将模型传递给视图引擎,该引擎运行您的视图以生成html - html返回给IIS,IIS将其发送到您的浏览器 - 您的浏览器将html显示为选择控件。 - 用户进行选择并在表单上单击“提交” - 浏览器编码其提交并将其发送到表单操作属性中的url(例如`
您没有提供足够的上下文,让我无法分析出什么问题,但我猜测`@ Html.DropDownList("Emails", Model.GetEmails())`正在生成类似于``的内容。这意味着当进行模型绑定时,它会查找提交的“电子邮件”输入,但找不到任何内容。相反,请尝试使用类似`@ Html.DropDownList("email", Model.GetEmails())`的东西来使其工作。
从语义上讲,这更正确,因为虽然控件以复数形式显示电子邮件,但用户实际上通过选择单个电子邮件与之交互。可以将其视为文本框,您不会将其命名为复数形式。

顺便提一下,您这里有几个巨大的安全漏洞。通过将电子邮件地址作为输入传递到您的方法中,似乎任何人都可以在其浏览器中打开开发者工具,并使用您的服务向任何电子邮件地址发送邮件!垃圾邮件发送者喜欢找到像这样不安全的服务。更好的解决方案是,将生成的选择列表中的值作为要发送电子邮件的用户的ID,并在Send方法中将该ID作为输入。此外,Send绝对不能通过Http GET进行访问(因此请在那里放置[HttpPost]属性!)。如果它允许GET请求,即使这是在登录页面后面,我也可以欺骗已登录的用户访问一个表单,其中包含<img src="http://yoursite.com/MyApp/Send/?email=personIWantToSpam@example.com" />,并且每次他们访问该页面时,某人都会收到垃圾邮件。


好的。是的,传递整数比字符串电子邮件更好。 - JoshYates1980

5

您可以在模型中使用字符串。

public string emails { get; set; };

然后在你的视图上使用DropDownListFor

@Html.DropDownListFor(x => x.emails, Model.GetEmails())

并且可以直接从 POST 模型中获取值。

[HttpPost]
public ActionResult Send(OverviewViewModel overviewModel)
{
    //here is the value from the drop down
    var theEmail = overviewModel.emails;
}

如果您有两个下拉列表,并且您必须检查用户选择了哪一个选项,哪一个没有选择? - Jogi
同样的概念仍然适用,只需在将List<SelectListItem>发送到视图之前设置“默认”值即可。您可以通过将项目的“Selected”属性设置为“true”(OP在上面执行此操作)来实现这一点。如果您的默认值在POST时仍然被模型选中,则可以假定用户未从该特定下拉列表中选择任何内容。 - X3074861X

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接