将选定的下拉列表值从View传递到Controller

时间:2014-01-12 13:35:31

标签: c# asp.net-mvc

我想从我的View中将参数(字符串)传递给我的Controller。该值应该是从视图中的下拉列表中选择的值。按钮单击后调用该方法,但在Controller中,参数始终为null。

在视图中:

    @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;
    }
你可以帮我搞定这项工作吗?我错过了什么? (顺便说一句,不要忘了Controller现在请回null:)。)。

2 个答案:

答案 0 :(得分:7)

从你的术语我猜你对发生的事情感到困惑。您永远不会从视图向控制器发送任何内容。相反,视图是组装Html以发送到Web浏览器的东西。所以实际发生的是:

  • 您的浏览器从您的服务器(IIS)请求/MyApp/Overview
  • IIS选择它并将其发送到Asp.Net
  • Asp.Net Mvc看到请求并通过路由确定您要在Overview
  • 上调用MyAppController方法
  • 该方法运行并生成模型
  • Asp.Net Mvc将模型传递给视图引擎,该引擎运行您的视图以生成html
  • 将html返回给IIS,将其发送到您的浏览器
  • 您的浏览器会将html显示为选择控件。
  • 用户进行选择并点击表单
  • 上的“提交”
  • 浏览器对其提交进行编码,并将其发送到表单的操作属性中的网址(例如<form method=POST action="/MyApp/Send>
  • IIS选择并将其发送到Asp.Net
  • Asp.Net Mvc看到请求并通过路由确定您要在Send
  • 上调用MyAppController方法
  • Asp.Net Mvc发现您的方法需要一个名为email的字符串参数,并尝试使用模型绑定
  • 在提交的表单数据中查找此信息
  • Asp.Net Mvc使用找到的参数值(如果可用)调用Send方法
  • ...

你没有为我提供足够的上下文来分析错误,但我的猜测@Html.DropDownList("Emails", Model.GetEmails())正在产生类似<select name="Emails"> ....</select>的内容。这意味着当模型绑定发生时,它正在寻找提交的“电子邮件”输入,但什么也没找到。而是尝试@Html.DropDownList("email", Model.GetEmails())之类的东西来使其发挥作用。

从语义上讲,这更为正确,因为当控件显示电子邮件(复数)时,用户通过选择电子邮件(单数)实际交互。可以把它想象成只是一个文本框,你不会用复数形式命名。

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

答案 1 :(得分: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;
}